how to multiply two unequal matrices in matlab? - matlab

c1=[1 2 3 4 5 6];
c2=[4 5 6 7 8 9 10];
c3=[3 5 7 11 12 13];
o1=intersect(c1,union(c2,c3));
o2=intersect(c2,union(c1,c3));
o3=intersect(c3,union(c1,c2));
p=(c1.*c2).*c3;
ND21=1;
ND22=2;
ND23=3;
CIa1=1/(ND21);
CIa2=1/(ND22);
CIa3=1/(ND23);
CIp1=(c1-o1)/p;
CIp2=(c2-o2)/p;
CIp3=(c3-o3)/p;
Eavg1=(Ecur1+Ecur2+Ecur3)/ND21;
Eavg2=(Ecur1+Ecur2+Ecur3)/ND22;
Eavg3=(Ecur1+Ecur2+Ecur3)/ND23;
i want multiply c1 and c2 which is an unequal matrix. I'm getting the following error:
??? Error using ==> times
Matrix dimensions must agree.
Error in ==> batwsn at 13
p=(c1.*c2).*c3;

The rule for matrix multiplication is that two matrices can be multiplied only when the number of columns in the first equals the number of rows in the second. This is a mathematical principle so basically you should not expect MatLab to do it.
The closest you can come is to pad one of the matrices with zeros to get the dimensions to match the rules - but you may not get the results you are expecting.

Related

Why slice of row vector does not return row vector?

I just started learning Julia. I would like to ask how make taking slice of a row vector return a row vector?
I searched and could not find an answer.
In Matlab, taking a slice of a row vector returns a row vector as expected. But in Julia it returns an array. Version 1.5.3 (2020-11-09)
>julia
julia> x=[1 2 3 4 5 6]
1×6 Array{Int64,2}:
1 2 3 4 5 6
julia> x[1:4]
4-element Array{Int64,1}:
1
2
3
4
In Matlab
>> x=[1 2 3 4 5 6 7]
>> x(1:4)
ans =
1 2 3 4
What is the correct way in Julia to do this? i.e. a slice of row vector returns a row vector, and similarly a slice of column vector returns column vector.
What you have there, is not a row vector but a matrix with shape 1x6, that is, a 2-dimensional array. If you are interested in a real deep dive into how vectors are handled in Julia you can read this issue: https://github.com/julialang/julia/issues/4774 which is called "Taking vector transposes seriously". You can see that a lot of thought went into this design.
Julia slices will drop dimensions in a predictable way: the number of dimensions of the output is equal to the sum of dimensions of the input indices. In your case, x[1:4], the input index slice is 1D, therefore the output is 1D. If you want the output to be 2D, you need 1D+1D=2D input indices:
jl> x[1:1, 1:4]
1×4 Matrix{Int64}:
1 2 3 4
Note that the following produces a 1D array
jl> x[1, 1:4]
4-element Vector{Int64}:
1
2
3
4
That is because the first index is a scalar, which is 0-dimensional, so the output is 0D+1D=1D.
This is even preserved for empty arrays:
jl> x[1:0, 1:4]
0×4 Matrix{Int64}
This is still a matrix, even though it has size 0x4.
You should also be aware that in most cases you should prefer proper vectors: [1, 2, 3, 4, 5, 6] instead of 1xN matrices, [1 2 3 4 5 6].
Short and doubtful:
y = x[1:4]'
Longer and more educational:
If you pay close attention to the output of
x = [1 2 3 4 5 6]
You will see the conditionality of the array (!) is two:
1×6 Array{Int64,2}:
1 2 3 4 5 6
That is, because you have not collected your elements in a column, but forced it into a row. To use julia efficiently, try to use column vectors as in
y = [1,2,3,4,5,6]
Or rely more on julias' functions and use
z = collect(1:6)
Julia uses column-major layout. Each column of an array is a continues area of memory. This makes operations on columns faster than operations on rows. Other languages might have different layouts. As a matter of fact, FORTRAN and MatLab also utilize column-major arrays. The C programming languages on the other hand, uses a row major layout.
EDIT: Apparently I got lost while writing.
I believe the correct way in julia is to do it all in column vectors. There sure is a bit of algebra where this is not possible. But for most programs, it should not matter what orientation a vectors has. Therefore, in julia use a column vector.
As #2419 wrote, what you are getting with x=[1 2 3 4 5 6] is actually a one-row matrix, and Julia is more performant with column vectors.
That's said, there are of course legit uses of matrices ;-)
Here is the long story.. when you have a matrix and slice it such that the result is a single row, it is automatically converted to a column vector:
julia> x = [1 2 3 4; 10 20 30 40; 100 200 300 400]
3×4 Matrix{Int64}:
1 2 3 4
10 20 30 40
100 200 300 400
julia> a = x[2,:]
4-element Vector{Int64}:
10
20
30
40
However if you slice it to 2 or more rows, it remains a Matrix:
julia> b = x[[2,3],:]
2×4 Matrix{Int64}:
10 20 30 40
100 200 300 400
I feel myself a bit perplex with this choice, but it is like this, and it will not change now.
Note that to retrieve back a row vector with the first case it is very easy:
julia> transpose(a) # or, equivalently, `a'`
1×4 transpose(::Vector{Int64}) with eltype Int64:
10 20 30 40
Important! transpose is a matrix operation and works only with numerical matrices (or vectors).
If your matrix includes non-numerical elements, as strings, transpose would generate an error and you should instead use permutedims:
julia> x2 = [1 2 "c" 4; 10 20 "cc" 40; 100 200 300 "ddd"]
3×4 Matrix{Any}:
1 2 "c" 4
10 20 "cc" 40
100 200 300 "ddd"
julia> a2 = x2[2,:]
4-element Vector{Any}:
10
20
"cc"
40
julia> transpose(a2)
1×4 transpose(::Vector{Any}) with eltype Any:
Error showing value of type LinearAlgebra.Transpose{Any, Vector{Any}}:
ERROR: MethodError: no method matching transpose(::String)
# [...]
julia> permutedims(a2)
1×4 Matrix{Any}:
10 20 "cc" 40
However transpose is faster:
julia> using BenchmarkTools
julia> #btime transpose(a)
21.971 ns (1 allocation: 16 bytes)
1×4 transpose(::Vector{Int64}) with eltype Int64:
10 20 30 40
julia> #btime permutedims(a)
66.289 ns (2 allocations: 96 bytes)
1×4 Matrix{Int64}:
10 20 30 40
So, if you are sure your matrix is numerical, use transpose, otherwise use permutedims.

How to generate all numbers randomly in the limit [m,n] in matlab?

How to generate all numbers randomly in the limit [m,n]. To generate all numbers from 6 to 12.. ie., the sequence must be like [7 12 11 9 8 10 6].
r = randi([6 12],1,7);
But this gives the result:
[12 11 12 7 9 10 12]
Here the numbers are repeated and the sequence does not contain all numbers from 6 to 12.
You can use randperm to make a list of random numbers between 1 and n (where n is the length of your vector), and use that to permute the vector.
v=6:12;
n=length(v);
I=randperm(n);
v(I)
Assuming you are sampling using a uniform distribution.
r = datasample(6:12,7,'Replace',false)
In a nutshell this does a random sampling without replacement, hence you get all the values from your original population in a random order.

Matlab, Sum Function for a Matrix row

Basically the sum function calculate the sum of the columns, that is to say if we have a 4x4 matrix we would get a 1X4 vector
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A)
ans =
34 34 34 34
But if I want to get the Summation of the rows then i have 2 methods, the first is to get the transpose of the matrix then get the summation of the transposed matrix,and finally get the transpose of the result...., The Second method is to use dimension argument for the Sum function "sum(A, 2)"
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A,2)
ans =
34
34
34
34
The problem is here I cannot understand how this is done, If anyone could please tell me the idea/concept behind this method,
It's hard to tell exactly how sum internally works, but we can guess it does something similar to this.
Matlab stores matrices (or N-dimensional arrays) in memory using column-major order. This means the order for the elements in memory for a 3 x 4 matrix is
1 4 7 10
2 5 8 11
3 6 9 12
So it first stores element (1,1), then (1,2), then (13), then (2,1), ...
In fact, this is the order you use when you apply linear indexing (that is, index a matrix with a single number). For example, let
A = [7 8 6 2
9 0 3 5
6 3 2 1];
Then A(4) gives 8.
With this in mind, it's easy to guess that what sum(A,1) does is traverse elements consecutively: A(1)+A(2)+A(3) to obtain the sum of the first column, then A(4)+A(5)+A(6) to sum the second column, etc. In contrast, sum(A,2) proceeds in steps of size(A,1) (3 in this example): A(1)+A(4)+A(7)+A(10) to compute the sum of the first row, etc.
As a side note, this is probably related with the observed fact that sum(A,1) is faster than sum(A,2).
I'm really not sure what you are asking. sum takes two inputs, the first of which is a multidimensional array A, say.
Now let's take sA = size(A), and d between 1 and ndims(A).
To understand what B = sum(A,d) does, first we find out what the size of B is.
That's easy, sB = sA; sB(d) = 1;. So in a way, it will "reduce" the size of A along dimension d.
The rest is trivial: every element in B is the sum of elements in A along dimension d.
Basically, sum(A) = sum(A,1) which outputs the sum of the columns in the matrix. 1 indicates the columns. So, sum(A,2) outputs the sum of the rows in the matrix. 2 indicating the rows. More than that, the sum command will output the entire matrix because there is only 2 dimensions (rows and columns)

How to convert 1D to 2D by Matlab program

I would like to ask a question about Matlab program.
I have vector a
a = [1 2 3 4 5 6 7 8 9 10 11 12];
I would like to convert vector a to 2D array. Normally, I use this code to convert it.
m =1;
for i=1:4
for j=1:3
b(i,j) = a(m);
m=m+1;
end
end
Then b is a 2D matrix.
b =
1 2 3
4 5 6
7 8 9
10 11 12
Anybody, have an idea to convert 1D to 2D without using loop.
Thanks,
Check out the reshape function and help page.
In particular,
B = reshape(A,m,n)
returns the m-by-n matrix B whose elements are taken column-wise from A. An error results if A does not have m*n elements.
Note that it is column-wise, so I suggest you make a matrix with 3 rows and 4 columns and then tip it on its side (A.' will take the transpose of a matrix).

Reconstruct matrix from diagonals in matlab

Given a vector of the counter-diagonals of a matrix in matlab, is there an easy way to reconstruct the matrix?
For example, given
x = [1 2 3 4 5 6 7 8 9]
is there any easy way to reconstruct it to the following?
1 2 4
3 5 7
6 8 9
This is made slightly easier by the fact that the dimensions of the original block are known. Reconstructing a rotation or transposition of the original matrix is fine, since rotating and transposing are easy to undo. Faster is better, this calculation has to be done on many xs.
Thanks!
You can create the corresponding Hankel matrix and use it for sorting (works only if the output is a square matrix!):
x = [1 2 3 4 5 6 7 8 9];
%# find size of output (works only with square arrays)
n=sqrt(length(x));
%# create Hankel matrix
hh = hankel(1:n,n:(2*n-1));
%# sort to get order of elements (conveniently, sort doesn't disturb ties)
[~,sortIdx]=sort(hh(:));
%# reshape and transpose
out = reshape(x(sortIdx),n,n)'; %'# SO formatting
out =
1 2 4
3 5 7
6 8 9