See if this is what you're after. I took the liberty of simplifying your MaximizeFunction, and in the process it became about twice as fast. I also got rid of the initial capitals. Best to avoid them, and avoid conflicting inadvertently with built-in functions.
In a comment you indicate that it might be sufficient to find the maximum over orthogonal matrices ($WW^* = I$). Then it is easy to do, since RotationMatrix[t] gives half of them. The other half of the orthogonal matrices are given by any reflection times a rotation matrix, such as {{1, 0}, {0, -1}}.RotationMatrix[t]. In all cases I tried, the p-value, as a function of t was the same for reflections as for rotations; further, the period as a function of t was π/2. (Perhaps one should check that.) If so, we can just use rotations.
maximizeFunction[W_, DataCoupled_] := Module[{newDataCouple},
newDataCouple = DataCoupled.Transpose[W];
IndependenceTest[First /@ newDataCouple, Last /@ newDataCouple]];
obj[t_?NumericQ, couple_] := maximizeFunction[RotationMatrix[t], couple]
We'll make up a large, random data set. It turns out there can be several local maxima, so using FindMaximum would probably give unreliable results. Another problem is that it takes a long time to evaluate a single function call. This makes using NMaximize take a very long time.
SeedRandom[1];
dc2 = RandomReal[{0, 1}, {120000, 2}]
(Table[obj[t, dc2], {t, 0.1, 1., 0.1}]; // AbsoluteTiming // First) / 10
0.2092696
Plot the function to get a sense of where the maximum is. (Plot from 0 to 2 Pi to check the periodicity.)
plot = Plot[obj[t, dc2], {t, 0, \[Pi]/2}, MaxRecursion -> 1]
![One period of obj[t, dc2]](../../images/76cbfc303ee1a9aca51698332a7d69da.webp)
We can get a rough approximation of the maximum from plot:
maxpt = Last@SortBy[Cases[plot, {_Real, _Real}, Infinity], Last]
{0.897961, 0.993164}
Use the first coordinate as an initial point for FindMaximum.
t0 = maxpt[[1]];
({pvalue, tsol} = FindMaximum[obj[t, dc2], {t, t0, t0 + 1/100}]) // AbsoluteTiming
{7.493610, {1., {t -> 0.891873}}}
Since we got a p-value of 1, we know it's the maximum.
Here is the optimal $W$:
RotationMatrix[t] /. tsol
{{0.627955, -0.778249}, {0.778249, 0.627955}}
Here's a function that does the whole thing:
findMax[couple_] := Block[{plot, t0},
plot = Plot[obj[t, couple], {t, 0, \[Pi]/2}, MaxRecursion -> 1];
t0 = First @ Last @ SortBy[Cases[plot, {_Real, _Real}, Infinity], Last];
FindMaximum[obj[t, couple], {t, t0, t0 + 1/100}]]
findMax[dc2] // AbsoluteTiming
{26.854463, {1., {t -> 0.891873}}}
If maximizing over rotation matrices is not sufficient, then you could do something similar with a different parametrization of the matrices. It tends to get harder as the dimension of the input domain increases.
If you know a formula for the p-value of the IndependenceTest, you might be able to use that to speed things up. (If there is a formula that can be differentiated, then FindMaximum can use Newton's method and so on.)
Wsuch that this function is closest to 1, there are a whole family of solutions. You can define a functiontomax[w1_?NumberQ, w2_?NumberQ, w3_?NumberQ, w4_?NumberQ] := MaximizeFunction[{{w1, w2}, {w3, w4}}, DataCouple]and useNMaximizeon this. However, plotting with any values ofw2,w3,w4you will find that there will always be a value ofw1which maximizes the function (to 1). (This is very inelegant coding but it should work). – Jonathan Shock May 22 '13 at 01:04Returnis not needed here and you can also drop the;. This is not just nitpicking: while in this particular example it does not make a difference if you use it or not, when used inside some functions, it will return from those functions and not from your function. – Szabolcs May 22 '13 at 01:55Flatten[List[Dot[W, #] & /@ DataCoupled], 1]with:DataCoupled.W– Mr.Wizard May 22 '13 at 06:25