I want to create an one column matrix with the 1st element to be -1, and all the other elements to be zero. However, I want to be able to make a matrix of this kind with arbitrary dimension, that is, an arbitrary number of rows.
5 Answers
Here is one way to do it.
makeArray[n_Integer] :=
Module[{a = ConstantArray[{0}, n]}, a[[1, 1]] = -1; a]
makeArray[4]
{{-1}, {0}, {0}, {0}}
There almost certainly more elegant ways to doing this, but this is the first thing that came to my mind.
-
$\begingroup$ Thanks your answer, it was very helpful! $\endgroup$ Jul 5, 2013 at 15:28
-
2$\begingroup$ I'm glad to help, but if you really like my answer, click on the accept button (check mark on the left of this answer). $\endgroup$ Jul 5, 2013 at 15:35
-
2$\begingroup$ @m_goldberg I always encourage users to wait longer before accepting an answer as I'm sure you've read before. It certainly doesn't hurt to point out that functionality as it's not entirely obvious, but unless you have strong feelings to the contrary I think it best not to encourage fast Accepts. $\endgroup$ Jul 5, 2013 at 18:07
-
$\begingroup$ @Mr.Wizard. I understand what you are saying and agree that I was hasty here. I will be more careful not to discourage potential additional answers in the future. $\endgroup$ Jul 5, 2013 at 20:27
Try this
coln[n_] := Join[{{-1}}, Table[{0}, {i, n}]];
(*n is the dimension*)
coln[5]
gives you {{-1}, {0}, {0}, {0}, {0}, {0}}
If you want to make a Column
or Matrix
with only one finite element (say x) at a position (say i for a column or i,j for a matrix) the KroneckerDelta
will be a better option.
col[x_, i_, n_] := Table[{x KroneckerDelta[i, j]}, {j, n}];
row[x_, i_, n_] := Table[x KroneckerDelta[i, j], {j, n}];
mat[x_, i_, j_, n_] := Table[x KroneckerDelta[i, p] KroneckerDelta[j, q], {p, n}, {q, n}];
then
mat[0.5,2,2,3]
will give you a matrix with 0.5 at (2,2) and zero everywhere else. Same for column and row.
You can also use sparse matrix to press in particular indices.Check this following example,
Normal[SparseArray[{1 -> -1}, RandomInteger[{2, 9}]]]
Output:{-1, 0, 0, 0, 0, 0, 0, 0}
You can put it in function to take it to more than 9 as number of rows.
Edit: As pointed out the snippet above will produce one row,so this minor improvisation will do it.
Normal[{SparseArray[{1 -> -1}, RandomInteger[{2, 9}]]}] // Transpose
Output:{{-1}, {0}, {0}, {0}, {0}, {0}}
-
$\begingroup$ SparseArray seems a nice way to go, but this produces a row vector, not a one-column, 2D matrix $\endgroup$ Jul 5, 2013 at 23:46
-
$\begingroup$ You can use this:
Normal[SparseArray[{{1, 1} -> -1}, {10, 1}]]
for 10 elements. $\endgroup$– MurtaJul 6, 2013 at 0:07
Transpose@DiagonalMatrix[{-1}, 0, {1, 5}]
=> {{-1}, {0}, {0}, {0}, {0}}
Edit
ArrayFlatten@{{-1}, {ConstantArray[{0}, 4]}}
=> {{-1}, {0}, {0}, {0}, {0}}
Edit
Probably the most transparent and concise version is this:
-Thread[{UnitVector[5, 1]}]
(* ==> {{-1}, {0}, {0}, {0}, {0}} *)
The first argument of UnitVector is the dimension, and the second argument is the position where the 1
appears. Obviously, this is exactly the kind of problem UnitVector
was made for.
End Edit
Another possibility:
-{KroneckerDelta[1, #]} & /@ Range[5]
(* ==> {{-1}, {0}, {0}, {0}, {0}} *)
This has the advantage of being easily generalized to setting any other element to -1
. For example, to do it with the third element:
-{KroneckerDelta[3, #]} & /@ Range[5]
(* ==> {{0}, {0}, {-1}, {0}, {0}} *)
-
$\begingroup$ Very nice. I was (also) not aware of you usage of Thread. (I have almost always used Transpose for this purpose).
Thread@DiagonalMatrix[{-1}, 0, {1, 5}]
==Transpose@ DiagonalMatrix[{-1}, 0, {1, 5}]
==-Thread[{UnitVector[5, 1]}]
==-Transpose@{UnitVector[5, 1]}
$\endgroup$– user1066Jul 6, 2013 at 8:41