Related
I'm started with TCL scripting recently. I'm finding difficulty in writing a script that adds two 3x3 matrices and prints the result.
Here is what I have tried:
set arr1 {{1 2 3} {4 5 6} {7 8 9}}
set arr2 {{3 2 1} {6 4 5} {8 9 7}}
foreach a $arr1 b $arr2 {
foreach c $a d $b {
set sum [expr $c + $d]
lappend z $sum
}
lappend y $z
unset z
}
puts $y
The above script gives me {4 4 4} {10 9 11} {15 17 16}
Is there any better way to get the same result ?
You have to do approximately that much work. However, there are some optimisations possible, of which the only truly important one is brace your expressions (to enable compiling them). Here's that addition as a one-liner:
set y [lmap a $arr1 b $arr2 {lmap c $a d $b {expr {$c+$d}}}]
Splitting things up, renaming variables, and adding some whitespace:
set y [lmap row1 $arr1 row2 $arr2 {
lmap cell1 $row1 cell2 $row2 {
expr {$cell1 + $cell2}
}
}]
lmap is like foreach except it makes a list out of the values it gets for evaluating its body (foreach throws that away). Using an lmap inside an lmap makes the addition work over the cells. (You'll get the most optimised compilation of this code if you put it in a procedure.)
Getting better than this requires using a package such as VecTcl that can hoist the computation into C.
in Mathematica, i am trying to manipulate a list such that i can start with something like:
myList = List[{a,b,c,d}];
a=12;
b=15;
c=7;
d=9;
I would then like to be able to reorder the list with the output being the variable names instead of numbers.
As said by #george in comment, one of the simplest way to do what you want
is to use transformation rules. They allow to substitute a value for
a symbol, without assigning a value to that symbol. For instance in your case
(I have mangled the order because it is not relevant here):
myValues = {d->9, a->12, b->15, c->7}
Transformation rules have two arguments and you can extract them. So here is a way to get the list of symbols from a list of transformation rules. The Sort is here to have the symbols in the alphabetical order.
myList = Sort[Map[First, myValues]]
{a, b, c, d}
To get a list of values, just apply the transformation rules to a list of symbol
with the /. operator
myList /. myValues
{12, 15, 7, 9}
Now we know how to do that, we can sort the symbol according to their numerical value
mySortedList = myList[[Ordering[ myList /. myValues]]]
{c, d, a, b}
Ordering gives the position of elements in a list if they were sorted.
Here we use the list of numerical values and apply its order to the list of symbols.
As there is no OrderingBy command in Mathematica as far as I know, you can
also order the symbols by a given function by applying it inside Ordering this way :
myList[[Ordering[Map[EulerPhi, myList /. myValues]]]]
{a, c, d, b}
I hope it fits your application.
One thing one does very often in Mathematica is to keep the association between symbols and values in form of transformation rules and manipulate it.
In your case, it could take this form :
SortBy[ myValues, Last]
{c -> 7, d -> 9, a -> 12, b -> 15}
or
SortBy[myValues, EulerPhi[Last[#]] &]
{a -> 12, c -> 7, d -> 9, b -> 15}
Then you can choose to extract what you want. That's how graph information is manipulated.
myList = HoldForm[{a, b, c, d}];
a = 12;
b = 15;
c = 7;
d = 9;
Last /# Sort[{ReleaseHold[#], #} & /# Thread[myList]]
{c, d, a, b}
Is there a pre-canned operation that would take two lists, say
a = { 1, 2, 3 }
b = { 2, 4, 8 }
and produce, without using a for loop, a new list where corresponding elements in each pair of lists have been multiplied
{ a[1] b[1], a[2] b[2], a[3] b[3] }
I was thinking there probably exists something like Inner[Times, a, b, Plus], but returns a list instead of a sum.
a = {1, 2, 3}
b = {2, 4, 8}
Thread[Times[a, b]]
Or, since Times[] threads element-wise over lists, simply:
a b
Please note that the efficiency of the two solutions is not the same:
i = RandomInteger[ 10, {5 10^7} ];
{First[ Timing [i i]], First[ Timing[ Thread[ Times [i,i]]]]}
(*
-> {0.422, 1.235}
*)
Edit
The behavior of Times[] is due to the Listable attribute. Look at this:
SetAttributes[f,Listable];
f[{1,2,3},{3,4,5}]
(*
-> {f[1,3],f[2,4],f[3,5]}
*)
You can do this using Inner by using List as the last argument:
In[5]:= Inner[Times, a, b, List]
Out[5]= {2, 8, 24}
but as others already mentioned, Times works automatically. In general for things like Inner, it's frequently useful to test things with "dummy" functions to see what the structure is:
In[7]:= Inner[f, a, b, g]
Out[7]= g[f[1, 2], f[2, 4], f[3, 8]]
and then work backwards from that to determine what the actual functions should be to give the desired result.
When I type the following
lis = {1, 2};
pos = Position[lis, 1];
result = Extract[lis, pos]
the result is always a list.
{1}
another example
lis = {{1}, {2}};
pos = Position[lis, {1}];
result = Extract[lis, pos]
{{1}}
Mathematica always adds an extra {} in the result. What would be the best way to remove this extra {}, other than applying Flatten[result,1] each time? And is there a case where removing these extra {} can cause a problem?
You probably realise this, but Position and Extract return lists because the requested values may be found in more than one position. So in general, removing the outer brackets doesn't make sense.
If you are sure the result is a singleton list, using Flatten would destroy information if the element is itself a list. For example,
Position[{{1}},1]
gives a list whose sole element is a list. So in this case, using Extract would make more sense.
Even so, there are many situations where Mathematica treats {x} very differently to x, as in
Position[1,1]
Position[{1},1]
which have very different results. So whether you can remove the outer braces from a one-member list depends on what you plan to do with it.
If I understood your question correctly, you are asking why
lis = {{1}, {2}};
pos = Position[lis, {1}];
result = Extract[lis, pos]
returns
{{1}}
rather than
{1}
The answer is, I think, simple: Position[lis,{1}] gives the position at which {1}, not 1 appears in lis; when you then go and look at that position using Extract, you do indeed get {1} which is then wrapped in a list (which is exactly what happened in the first case, when you looked for 1 and obtained {1} as a result; just replace 1 by {1}, because that is now what you are asking for.
To see this more clearly, try
lis = {f[1], f[2]};
pos = Position[lis, f[1]];
result = Extract[lis, pos]
which gives
{f[1]}
The point here is that List in {1} (which is the same as List[1] if you check look at the FullForm) before was just a head, like f here. Should mathematica have remove f here? If not, then why should it have removed the innermost List earlier?
And finally, if you really want to remove the inner {} in your second example, try
lis = {{1}, {2, {1}}};
pos = Position[lis, {1}];
result = Extract[lis, pos, #[[1]] &]
giving
{1, 1}
EDIT: I am becoming puzzled with some of the answers here. If I do
lis = {{1}, {2, {1, 2, {1}}}};
pos = Position[lis, 1];
result = Extract[lis, pos]
then I get
{1, 1, 1}
in result. I only get the extra brackets when I actually obtain the positions of {1} in pos instead of the positions of 1 (and then when I look at those positions, I find {1}). Or am I missing something in your question?
Short answer: You should probably use First#Position[...]
Long answer:
Lets separate the question to 2 parts:
Why do you have the extra {} in the result for Position?
i.e. why:
lis = {1, 2};
Position[lis, 1]
returns {{1}}?
This is in order to work consistently with n-dimensional list, that may have the requested values in more than one position. For example:
lis = {{1, 2, 3}, {1, 5, 6}, {1, 2, 1}};
Position[lis, 1]
returns {{1, 1}, {2, 1}, {3, 1}, {3, 3}}
which is a list of the coordinates the result is found in.
So in your case:
lis = {1, 2};
Position[lis, 1]
return {{1}}, as in: we found your requested value one time, in the coordinate-set {1}.
Now, a lot of times Mathematica assume that there might be a list of solutions (for example, in Solve), but the user know that he expect only one. A suitable code to this in your case will be First#Position[...]. this will return the first (and, assumebly, only) element in the list of positions --
So, if you are sure that the element you are searching for exist only once in the list and want to know where, use this way.
Why do you have the extra {} in the result for Extract?
Extract can work in two different ways.
If I'm doing Extract[{{a, b, c}, {d, e, f}, {g, e, h}}, {1, 2}]
I will get b, so extract with a 1 dimensional list of is just choosing and returning this element. In fact, Extract[lis, {1, 2}] is equal to lis[[1, 2]]
If I'm doing Extract[{{a, b, c}, {d, e, f}, {g, e, h}}, {{1, 2}, {3, 4}}]
I will get {b, h}, so extract with a 2 dimensional list is choosing and returning a list of elements.
In your case(s), you are doing Extract[lis, {{1}}], as in: give me a list containing only the element lis[[1]]. The result is always this element in a list, which is the extra {}
I have the following Nested table
(myinputmatrix = Table[Nest[function, myinputmatrix[[i]][[j]],
myinputmatrix[[i]][[j]][[2]][[2]] +
myinputmatrix[[i]][[j]][[3]][[2]]], {i,
Dimensions[myinputmatrix][[1]]}, {j,
Dimensions[myinputmatrix][[2]]}]) // TableForm
fq[k_?NumericQ] := Count[RandomReal[{0, 1}, k], x_ /; x < .1]
function[x_List] := ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #1,
{2, 2} -> x[[2]][[2]] + #1,
{3, 1} -> x[[3]][[1]] - #2, {3, 2} ->
x[[3]][[2]] + #2}] &[fq[x[[2]][[1]]], fq[x[[2]][[1]]]];
My problem is that I want to add only the #1 in the bold part above, but not only the new one, I want it to add all #1 for the n times (Nest function times]
If I try the function
function[x_List] := ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #1, {2, 2} -> #1,
{3, 1} -> x[[3]][[1]] - #2, {3, 2} -> #2}] &[fq[x[[2]][[1]]],
fq[x[[2]][[1]]]];
I am having as a result the last value of fq[k]. I thought of replacing that part in my table with 0 but is not going to work since I am using it in my nested list, also I thought of substricting that part from my initial table but I am not sure which way is the best to do it and if the way I am thinking is the correct one. Can anyone help me?
If I may restate the problem and hopefully clarify the question for myself. At each iteration in the Nest, you want to add not the current (random) output from fq, but the cumulation of the current and all past values of it. But because the random output depends at each iteration on the input matrix, you need to calculate both the random number and the current value of the matrix in the same iteration.
If that hadn't been true you could use Fold.
Restating fq as Sasha suggested EDIT with some type checking to avoid problems with incorrect input:
fq[k_Integer?Positive]:=RandomVariate[BinomialDistribution[k,.1]]
You might want to add some other error checking code. Something like this, depending on your requirements, might do.
fq[0]:= 0;
fq[k_Real?Positive]:=RandomVariate[BinomialDistribution[Round[k],.1]]
You need function to take the random numbers as parameters. EDIT 1 and 2 I have changed the syntax of this function to use the parameters explicitly instead of the original question's anonymous function within a function. This should avoid some syntax errors. Also note that I have used "NumericQ" rather than "Real" as the type for the rv1 and rv2 parameters, because they can be integers at the start of the Nest iteration.
function[x_List, rv1_?NumericQ, rv2_?NumericQ] := ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - rv1, {2, 2} -> rv1,
{3, 1} -> x[[3]][[1]] - rv2, {3, 2} -> rv2}]
And then pass the current random number as a local constant using With to a Nest function that works on a list containing your matrix and the cumulation of the random variates. I have used myoutputmatrix because I really don't like the idea of rewriting existing expressions all the time. That's just me. Now, the one other thing is that you need to set n, the number of iterates. I've set it to 5 but you can make this a parameter in a function if you want (see below).
(myoutputmatrix = Table[ First[Nest[With[{rv=fq[#1[[1]][[2]][[1]] ]},
{function[#1[[1]],rv, rv+#1[[2]] ],rv+#1[[2]] }]&,
{ myinputmatrix[[i]][[j]], 0 }, 5]],
{i, Dimensions[myinputmatrix][[1]]}, {j,
Dimensions[myinputmatrix][[2]]}]) // TableForm
The First is there because in the end you only want the matrix, not the cumulation of the random variates.
outputmatrix[input_List, n_Integer?Positive] /;
Length[Dimensions[input]] == 4 :=
Table[First[
Nest[With[{rv = fq[#1[[1]][[2]][[1]]]}, {function[#1[[1]], rv,
rv + #1[[2]]], rv + #1[[2]]}] &, {input[[i]][[j]], 0}, n]],
{i, Dimensions[input][[1]]}, {j, Dimensions[input][[2]]}]
outputmatrix[myinputmatrix, 10] // TableForm
EDIT I have checked this now and it runs, but note that you can get negative numbers in the output, which is not what you want, I don't think.