Is it possible to have lists or arrays passed as outputs of components in openMDAO?
Since my problem relies on 6x6 matrices to solve an equation of motion in 6 degrees of freedom, I would like to be able to do the following:
M = np.ones([6, 6])
outputs['M'] = M
However, that results in an error:
ValueError: cannot reshape array of size 36 into shape (1,)
Is there any way to avoid passing each of 36 values seperately?
Yes, you can declare an output of any size or shape in your component's setup method by doing the following:
self.add_output('M', shape=(6, 6))
or
self.add_output('M', val=np.ones((6, 6)))
Related
I want to have an array of images. For example, I would have a 4x1 array, (called imslice below) where each element is a nxnx3 image.
I want to do this to to do matrix operations on my imslice matrix like it was a normal matrix. For example, multiply it by a regular 2x2 matrix (called V.) When I try an do this right now, I am getting an array with 5 dimensions and when I try and multiply it by my V matrix I am getting the error that the dimensions don't agree (even though mathematically it's fine because the inner dimensions agree.)
Code:
imslice = np.array(([imslice1q, imslice2q, imslice3q, imslice4q]))
print imslice.shape
V = mh.gen_vmonde(4, 2, 1)
V.shape
C = np.dot(np.transpose(V), imslice)
------------------------------------------- ValueError Traceback (most recent call
last)
in ()
6 V.shape
7
----> 8 np.dot(np.transpose(V), imslice)
9
ValueError: shapes (6,4) and (4,178,178,3) not aligned: 4 (dim 1) !=
178 (dim 2)
Both np.dot and np.matmul treat more-than-two-dimensional arrays as stacks of matrices, so the last and last but one dimensions have to match.
A simple workaround in your case would be transposing:
np.dot(imslice.T, V).T
If you need something more flexible, there is np.einsum:
np.einsum('ji,jklm', V, imslice)
I have a matrix A of size 3780x30974. This matrix consists of 0 and 1. I would like to calculate the sum of fixed windows of length 21 (180 blocks). This should be reiterated, so that the output returns a vector of size 180x30974.
If the first 21 values in a column have a value of 1, the output should return 21. However, if the following 21 values have a value of 1 again, it should return 21 as well. In my code, it accumulates the values, so I obtain 42.
I have t=3780, p=180, w=21;
B = movsum(A,w); % the sum of a moving window with width w
This question is somehow related to a question previously asked, yet with a different problem setting. I thought about a loop to say "perform from t=1:p", yet it didn't work.
result = permute(sum(reshape(A, w, [], size(A,2)), 1), [2 3 1]);
This works as follows: reshape A into a 3D array of size 21×180×30974:
reshape(A, w, [], size(A,2)), 1)
then sum along the first dimension
sum(..., 1)
and finally remove the first (singleton) dimension by permuting it to the end:
permute(..., [2 3 1])
Note that Matlab arrays have an infinite number of trailing singleton dimensions, so moving a singleton dimension to the end is the same as removing it.
If I have a square matrix of arrays such as:
[1,2], [2,3]
[5,9], [1,4]
And I want to get the mean of the first values in the arrays of each row such:
1.5
3
Is this possible in Matlab?
I've used the mean(matrix, 2) command to do this with a matrix of single values, but I'm not sure how to extend this to deal with the arrays.
Get the first elements in all arrays of matrix, then call mean function
mean(matrix(:,:,1))
maybe you need to reshape before call mean
a = matrix(:,:,1);
mean(a(:))
You can apply mean function inside mean function to get the total mean value of the 2D array at index 1. You can do similary with array at index 2. Consider the following snapshot.
After staring at your problem for a long time, it looks like your input is a 3D matrix where each row of your formatting corresponds to a 2D matrix slice. Therefore, in proper MATLAB syntax, your matrix is actually:
M = cat(3, [1,2; 2,3], [5,9; 1,4]);
We thus get:
>> M = cat(3, [1,2; 2,3], [5,9; 1,4])
M(:,:,1) =
1 2
2 3
M(:,:,2) =
5 9
1 4
The first slice is the matrix [1,2; 2,3] and the second slice is [5,9; 1,4]. From what it looks like, you would like the mean of only the first column of every slice and return this as a single vector of values. Therefore, use the mean function and index into the first column for all rows and slices. This will unfortunately become a singleton 3D array so you'll need to squeeze out the singleton dimensions.
Without further ado:
O = squeeze(mean(M(:,1,:)))
We thus get:
>> O = squeeze(mean(M(:,1,:)))
O =
1.5000
3.0000
Basically, I want to sample 9 independent realizations for the uniform distribution U(0,1) 2578 times, and this works fine, using either
replicate(2578,{runif(9,0,1)})
or
F=c()
for (i in 1:2578){
F[i,]=runif(9,0,1)
}
Now I want this to be repeated let's say 10 times, i.e. creating 10 new 2578x9 samples. I want to create a multidimensional array, or to visualize it better a rectangular parallelepiped with length 9, height 2578, and width whatever (10, 1000, 100000, ...). How can I achieve this?
I think your simulated data could benefit from being structured directly into an array: that would make them much easier to handle:
dims <- c(2578, 9, 100)
tmp <- runif(prod(dims))
A <- array(tmp, dims)
In MATLAB, I have a defined cell array C of
size(C) = 1 by 150
Each matrix T of this cell C is of size
size(C{i}) = 8 by 16
I am wondering if there is a way to define a new multidimension (3D) matrix M that is of size 8 by 16 by 150
That is when I write the command size(M) I get 8 by 16 by 150
Thank you! Looking forward for your answers
If I'm understanding your problem correctly, you have a cell array of 150 cells, and each cell element is 8 x 16, and you wish to stack all of these matrices together in the third dimension so you have a 3D matrix of size 8 x 16 x 150.
It's a simple as:
M = cat(3, C{:});
This syntax may look strange, but it's very valid. The command cat performs concatenation of matrices where the first parameter is the dimension you want to concatenate to... so in your case, that's the third dimension, and the parameters after are the matrices you want to concatenate to make the final matrix.
Doing C{:} creates what is known as a comma-separated list. This is equivalent to typing out the following syntax in MATLAB:
C{1}, C{2}, C{3}, ..., C{150}
Therefore, by doing cat(3, C{:});, what you're really doing is:
cat(3, C{1}, C{2}, C{3}, ..., C{150});
As such, you're taking all of the 150 cells and concatenating them all together in the third dimension. However, instead of having to type out 150 individual cell entries, that is encapsulated by creating a comma-separated list via C{:}.