Re: Function construction and also symmetric
- To: mathgroup at smc.vnet.net
- Subject: [mg108513] Re: Function construction and also symmetric
- From: danl at wolfram.com
- Date: Sun, 21 Mar 2010 02:06:04 -0500 (EST)
> Thank you Ray.
>
> Have you any thoughts about the second question?
>
> Cheers,
> Mark
Not sure if this is quite what you have in mind, but it might be a start.
makeSymmetricMatrixFunction[n_Integer /; n > 0] :=
makeSymmetricMatrix[n] := Module[
{vals = RandomReal[1, n*(n - 1)/2], i = 0, mat},
mat = Table[
If[j == k, 1/2, If[j < k, i++; vals[[i]], 0]], {j, n}, {k, n}];
mat + Transpose[mat]
]
In[61]:= makeSymmetricMatrixFunction[4]
In[62]:= ?? makeSymmetricMatrix
Global`makeSymmetricMatrix
makeSymmetricMatrix[4]:=Module[{vals$=RandomReal[1,(4
(4-1))/2],i$=0,mat$},mat$=Table[If[j==k,1/2,If[j<k,i$++;vals$[[i$]],0]],{j,4},{k,4}];mat$+Transpose[mat$]]
We'll try it out on n=4, show that Information records the DownValue, then
run it on n=3 (getting nothing) and n=4 (getting a matrix of the requested
type).
In[63]:= makeSymmetricMatrix[3]
Out[63]= makeSymmetricMatrix[3]
In[64]:= makeSymmetricMatrix[4]
Out[64]= {{1, 0.639154, 0.567109, 0.350681}, {0.639154, 1, 0.0392727,
0.418976}, {0.567109, 0.0392727, 1, 0.625158}, {0.350681, 0.418976,
0.625158, 1}}
Daniel Lichtblau
Wolfram Research
> "Ray Koopman" <koopman at sfu.ca> wrote in message
> news:hnvo3m$egu$1 at smc.vnet.net...
>> On Mar 19, 12:47 am, "Diamond, Mark" <d... at dot.dot> wrote:
>>> I am trying to construct a number of symmetric matrices with unit
>>> diagonal and random numbers in the off-diagonal entries. The matrices
>>> are of steadily increasing size. I have been constructing the
>>> matrices from random vectors with the correct number of off-diagonal
>>> entries, so that for a 3x3 matrix I have:
>>>
>>> symmetricMatrix[L_,3] := (* I have changed lowercase "l" *)
>>> {{1, L[[1]], L[[2]]}, (* to uppercase "L" throughout *)
>>> {L[[1]], 1, L[[3]]}, (* to avoid confusing "l" and "1" *)
>>> {L[[2]], L[[3]], 1}}
>>>
>>> symmetricMatrix[#,3]&/@RandomReal[{0,1},{10000,3}]
>>>
>>> or, for a 4x4 matrix
>>>
>>> symmetricMatrix[L_,6] :=
>>> {{1, L[[1]], L[[2]], L[[4]]},
>>> {L[[1]], 1, L[[3]], L[[5]]},
>>> {L[[2]], L[[3]], 1, L[[6]]},
>>> {L[[4]], L[[5]], L[[6]], 1}}
>>>
>>> symmetricMatrix[#,6]&/@RandomReal[{0,1},{10000,6}]
>>>
>>> The method works but writing the function symmetricMatrix by hand
>>> error-prone for large matrices. ...
>>>
>>> My first question is whether I have overlooked a much better (i.e.,
>>> computationally faster) way of producing the matrices. Something
>>> which avoids all the calls to Part (e.g., L[[7]]) might be good.
>>>
>>> My second question relates not only to symmetric matrices but to a
>>> problem that I face frequently in other areas. Is there a way of
>>> constructing the symmetricMatrix function automatically? This is
>>> different from the question about a good way of constructing symmetric
>>> matrices. Here I am asking whether, given an appropriate matrix size,
>>> n, I can get Mathematica to create the static function in the form
>>> that I have written symmetricMatrix[3] and symmetricMatrix[6] ...
>>> so that, for example, if I enter
>>>
>>> makeStaticSymmetricMatrixFunctionForSize[3]
>>>
>>> and then enter
>>>
>>> ?makeSymmetricMatricFunction
>>>
>>> Mathematic will show me that there now exists a function like
>>>
>>> symmetricMatrix[L_,3] :=
>>> {{1, L[[1]], L[[2]]},
>>> {L[[1]], 1, L[[3]]},
>>> {L[[2]], L[[3]], 1}}
>>>
>>> ??
>>>
>>> I would appreciate any help or suggestions.
>>>
>>> Cheers,
>>> Mark Diamond
>>
>> First, the solution to a slightly different problem.
>>
>> Lix[i,j] = Lix[j,i] returns the linear index of row i, column j,
>> in a symmetric matrix whose nonredundant elements are numbered as
>>
>> 1
>> 2 3
>> 4 5 6
>> 7 8 9 10
>> etc.
>>
>> Lix[i_,j_] := #(#-1)/2 & @ Max[i,j] + Min[i,j]
>>
>> With[{n = 6}, Table[Lix[i,j],{i,n},{j,n}] ]
>>
>> {{ 1, 2, 4, 7, 11, 16},
>> { 2, 3, 5, 8, 12, 17},
>> { 4, 5, 6, 9, 13, 18},
>> { 7, 8, 9, 10, 14, 19},
>> {11, 12, 13, 14, 15, 20},
>> {16, 17, 18, 19, 20, 21}}]
>>
>> This will create a symmetric random matrix:
>>
>> With[{n = 4}, Table[#[[Lix[i,j]]],{i,n},{j,n}]& @
>> Table[ Random[Integer,9],{n(n+1)/2}] ]
>>
>> {{2, 7, 0, 9},
>> {7, 1, 0, 0},
>> {0, 0, 8, 5},
>> {9, 0, 5, 0}}]
>>
>> Now to your problem. The easiest solution is to
>> insert the diagonals into the list of offidagonals.
>>
>> symat[L_,n_,d_] := Table[#[[Lix[i,j]]],{i,n},{j,n}]& @
>> Insert[L,d,Table[{i*i+i},{i,0,n-1}]/2+1]
>>
>> symat[Range@15, 6, 0]
>>
>> {{ 0, 1, 2, 4, 7, 11},
>> { 1, 0, 3, 5, 8, 12},
>> { 2, 3, 0, 6, 9, 13},
>> { 4, 5, 6, 0, 10, 14},
>> { 7, 8, 9, 10, 0, 15},
>> {11, 12, 13, 14, 15, 0}}
>>
>
>
>
>