Un-normalized null space basis of a matrix in R [duplicate] - r

This question already has an answer here:
Solve homogenous system Ax = 0 for any m * n matrix A in R (find null space basis for A)
(1 answer)
Closed 4 years ago.
I am using the pracma package, which contains the function nullspace(), returning normalized basis vectors of the Null(A):
> require(pracma)
> (A = matrix(c(1,2,3,4,5,6), nrow=2, byrow=T))
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
> nullspace(A)
[,1]
[1,] 0.4082483
[2,] -0.8164966
[3,] 0.4082483
which is perfectly fine. However (don't ask), I want to quickly check the values I'd get if I were to produce the reduced row echelon form:
> rref(A)
[,1] [,2] [,3]
[1,] 1 0 -1
[2,] 0 1 2
and from there "manually" figure out the null space as
N(A) = [1, -2, 1]'
Yes, the latter is a scalar multiple of the former:
> c(1,-2,1)/nullspace(A)
[,1]
[1,] 2.44949
[2,] 2.44949
[3,] 2.44949
but I'd still like to get the latter, non-normalized form of a basis of the null space, as though the values were directly obtained from the reduced row echelon matrix.

You may want to try
B = rref(A)
solve(B[,1:2], -B[,3])
This gives you the combination your need for the first two columns to get one unit of the third column. Just add one to get your result.
Similarly for the case where size of null space is larger than one.

Related

How to convert a matrix from a list of matrices to an unlisted 2D numeric/matrix without flattening to a vector in R?

So I have a large list of matrices and I want to be able to take them one by one and unlist them into their normal 2D individual matrices. So let's say I have a list of matrices examplelist. I obtained the list with this code:
examplelist <- lapply(listofimages, readImage)
And here is one sample image 512x512 .tif which would be one of the matrices in the list of matrices :
The list looks like this:
I want to take out one matrix at a time as a 2D 512x512 matrix but when I try to trim out the other data manually its still a list element (single quotes to make the index not referenced):
a <- as.matrix(examplelist['1'])
b <- a[,]
And when I do this it flattens into a 1D vector:
b <- as.numeric(unlist(examplelist['1']))
Which is 262144 x 1 instead of 512 x 512.
Ive tried converting it to a data table, data frame, and a few other things and then when I get to trying to make it numeric:
as.numeric(b)
I get this error:
Using dput, it lists this as the error:
Is there an easy way to unlist a square matrix from a list of matrices and get it in its original 512 x 512 form rather than a 1D vector (as seen above)?
I tried trimming dimensions (seen above) to get rid of some of the other info but it threw an error. I also tried accessing just the data attributes using '#' and '$' but that didn't work either.
If I try this:
b <- as.data.table(examplelist['1'])
It just gives me another 262144 x 1 1D vector instead of the desired 2D matrix.
This solution and this, don't work because I dont want a 1D vector or to only convert elements (I want the whole matrix) as numeric elements.
To extract an element of a list you need to use double brackets. Consider the example below. Let's create a list of matrices.
# Dummy list
foo <- list(first = matrix(runif(16), ncol = 4),
second = matrix(runif(16), ncol = 4))
This looks like the following:
# Quick peek
print(foo)
#> $first
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
#>
#> $second
#> [,1] [,2] [,3] [,4]
#> [1,] 0.57426947 0.59617809 0.05355548 0.05962695
#> [2,] 0.60420788 0.06640785 0.43616808 0.03359352
#> [3,] 0.44216820 0.58033207 0.22686284 0.42624557
#> [4,] 0.08838313 0.27258925 0.71353586 0.76606084
Now, let's have a look at the first element using just one set of brackets.
# Extract one element as a list
a <- foo['first'] # Or foo[1]
# Examine output
print(a)
#> $first
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
class(a)
#> [1] "list"
You'll notice it's a list. Let's try using two sets of brackets.
# Extract one element
b <- foo[['first']] # Or foo[[1]]
# Examine output
print(b)
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
class(b)
#> [1] "matrix"
Created on 2019-06-18 by the reprex package (v0.3.0)
It's a matrix! Plus, it maintains the original structure of the matrix.

R how to stack image from their matrix value

I got many matrix of size 300*300, which are saved in a list, named L. This is binary matrix, i only have 0 and 1 values.
I plot image from those matrix (for exemple with c.img).
What is the best way to create a stack of those matrix? I want to create a new matrix, and or the pixel at the (i,j) position, i want to look in all my matrix saved in L, and if one or more matrix have a 1 at this position, then the (i,j) pixel in my new matrix will have value 1, else 0.
Here a pseudo code to help you understand my goal
L <- list(rep(matrix(0 or 1,300,300),n)
new_matrix<-matrix(0,300,300)
new_matrix[i,j]<- max(L[i,j])
but this code doesnt work because data is a list. I'm prety sure sure i can achieve this task using 3 loop (i,j,n), but because i got many matrix that'll take too long and i'm looking for a faster solution.
You can use :
matrix(as.numeric(Reduce(`+`, data) > 0), 300, 300)
Sum all matrix then convert values greater than 0 to 1 with as.numeric.
I would use a multi-dimensional array if all images are the same dimensions.
# Two matrices
m1 <- matrix(1,5,5)
m2 <- matrix(0,5,5)
# Placing them in an array (two matrices of dimension 5x5)
my_array <- array(c(m1,m2),dim = c(5,5,2))
# Investigating content of position 1,1 for matrices 1 to 2
my_array[1,1,1:2]
[1] 1 0
# You can even look at larger regions across matrices
> my_array[1:3,1:3,1:2]
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 2
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0

Converting list to dataframe for use in ggplot

I've got a list called res that looks like this:
[[1]]
[,1] [,2]
[1,] 275.0637 273.9386
[2,] 5.707791 5.755798
[[2]]
[,1] [,2]
[1,] 126.8435 59.08806
[2,] 4.867521 3.258545
[[3]]
[,1] [,2]
[1,] 23.50188 60.96321
[2,] 2.036354 3.737291
The list contains results from a simulation run a total of 6 times. I set a parameter of interest at three different values, '0' (ie., [[1]]), '25' (i.e.,[[2]]), and '50' (i.e.,[[3]]). Since the model includes a great deal of randomness I ran the model twice for each value (i.e., [,1], [,2]). I asked the model to record two results, 'time feeding' (i.e., [1,] and 'distance traveled' (i.e., [2,]) for each iteration. Ultimately I will iterate the model 30 times for each variable setting. I'd like to use ggplot to create a boxplot showing 'time feeding' and 'distance traveled' for each of the three simulation settings (i.e., 0,25,50). I believe ggplot can't plot a list so I tried to convert res to a dataframe using res2 <- data.frame(res) which looked like:
X1 X2 X1.1 X2.1 X1.2 X2.2
1 275.0637 273.9386 126.8435 59.08806 23.50188 60.96321
2 5.707791 5.755798 4.867521 3.258545 2.036354 3.737291
This doesn't quite look right to me because now the results from all three simulations are on the same row. Any help on bringing this data into ggplot to create a boxplot with would be really helpful. Thanks in advance!
--Neil
Assuming ll is your list , you can use do.call and rbind like this :
do.call(rbind,lapply(seq_along(ll),
function(x)data.frame(ll[[x]],iter=x)))
X..1. X..2. iter
[1,] 275.063700 273.938600 1
[2,] 5.707791 5.755798 1
[1,]1 126.843500 59.088060 2
[2,]1 4.867521 3.258545 2
[1,]2 23.501880 60.963210 3
[2,]2 2.036354 3.737291 3
EDIT after op clarication:
interest <- c(0,25,50)
do.call(rbind,lapply(seq_along(ll),
function(x)data.frame(x= unlist(ll[[x]]),interst=interest[x])))
interst=interest[x] .... [TRUNCATED]
x interst
X..1.1 275.063700 0
X..1.2 5.707791 0
X..2.1 273.938600 0
X..2.2 5.755798 0
X..1.11 126.843500 25
X..1.21 4.867521 25
X..2.11 59.088060 25
X..2.21 3.258545 25
X..1.12 23.501880 50
X..1.22 2.036354 50
X..2.12 60.963210 50
X..2.22 3.737291 50
EDIT since OP don't provide data here ll :
res <- list(read.table(text='
[,1] [,2]
[1,] 275.0637 273.9386
[2,] 5.707791 5.755798'),
read.table(text='
[,1] [,2]
[1,] 126.8435 59.08806
[2,] 4.867521 3.258545'),
read.table(text='
[,1] [,2]
[1,] 23.50188 60.96321
[2,] 2.036354 3.737291'))
I would do
names(res) = c("0", "25", "50")
m = reshape2::melt(res, id = 1)
but maybe it doesn't work, I tried it in my head because you didn't provide data in usable form.

Delete parts of a matrix that satisfy a condition in R

I would like to delete rows from a large matrix using the following criteria:
Any row that contains 100 in its second column should be removed.
How can this be done? I know how to select those rows but I'm not sure how to remove them using a rule.
R > mat = matrix(c(1,2,3,100,200,300), 3,2)
R > mat
[,1] [,2]
[1,] 1 100
[2,] 2 200
[3,] 3 300
R > (index = mat[,2] == 100)
[1] TRUE FALSE FALSE
R > mat[index, ]
[1] 1 100
R > mat[!index, ]
[,1] [,2]
[1,] 2 200
[2,] 3 300
Previously I was confused by the index with another method which, here is the solution by which:
R > (index2 = which(mat[,2] == 100))
[1] 1
R > mat[-index2, ]
[,1] [,2]
[1,] 2 200
[2,] 3 300
Watch out the different use for those index (! and -).
Here's how I would do it in Matlab with a matrix A.
Option 1
for (i=size(A,1):-1:0)
if (A(i,2)==100)
A(i,:)=[];
end
end
This loops over rows (starting at the bottom), and sets any row with 100 in the 2nd element to an empty set, which effectively deletes it.
Maybe you can convert this to r, or maybe it will help somebody else who is having this problem.
Option 2
logicalIndex=(A(:,2)==100);
A(logicalIndex,:)=[];
This first finds rows with 100 in the 2nd column, then deletes them all.

Select subset of N-dimensional array with m-dimensional array?

Is it possible to select a subset of a three dimensional array with a two-dimensional binary array? I would like to be able to do this so that I can push values into the selection
For example I have an array dim(a) = (lat, long, time), and I want to select with dim(b) = (lat, long) which is an array full of TRUE/FALSE values. I want to be able to do something like:
> a <- array(c(1,2,3,4,5,6,7,8),c(2,2,2))
> b <- matrix(c(0,1,0,0), c(2,2))==TRUE
> a[[b]] <- 0
> a
, , 1
[,1] [,2]
[1,] 1 3
[2,] 0 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 0 8
Edit : ok, so this looks like a stupid question, as I just realised that it works exactly as stated above, if you use a[b] <- 0 (single brackets). But that only works if the dimension(s) you want to span are the ones at the end. So, to make it more interesting:
How can you do this if the dimension you want to span is the first or second dimension - eg. if dim(b)==(lat, years)?
R supports matrix subsetting of arrays with the [ operator (i.e. single bracket, not double - the double bracket will always only return a single element):
a[b] <- 0
a
, , 1
[,1] [,2]
[1,] 1 3
[2,] 0 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 0 8
Notice that this is somewhat different from the result you specify in your question. In your question, the second element (i.e. bottom left element of the matrix) is 1, thus you would expect the second element of each array slice to be modified. (In other words not the first, as you have in your example.)

Resources