doing operations on 1xN struct

i have a structure that holds some data,
the structure is an array of structures (size of 1xN, N is an integer)
one of the data each struct holds is a 3 by 3 matrics with xyz positions of 3 points in space.
so a 1x2 structure will hold 2 matrics 3x3.
i need the square root of each row, but i dont know how to do it without a loop.
is there a way to get the square root of each row, within all the structures in the array without a loop?

Respuestas (1)

Voss
Voss el 30 de Sept. de 2024
Constructing a structure array:
N = 2;
S = struct('matrix_field',permute(num2cell(rand(3,3,N),[1 2]),[1 3 2]),'other_field',{'something','else'})
S = 1x2 struct array with fields:
matrix_field other_field
S(1)
ans = struct with fields:
matrix_field: [3x3 double] other_field: 'something'
S(2)
ans = struct with fields:
matrix_field: [3x3 double] other_field: 'else'
If it's convenient for subsequent operations you need to do, you can concatenate all N 3x3 matrices into a 3x3xN array and take the square root of that, resulting in another 3x3xN array:
M = sqrt(cat(3,S.matrix_field));
disp(M)
(:,:,1) = 0.7156 0.3034 0.9401 0.8949 0.9009 0.7890 0.2553 0.7022 0.2558 (:,:,2) = 0.5955 0.3100 0.4549 0.9599 0.8806 0.8985 0.4852 0.8184 0.8393
Otherwise, you can use arrayfun, which is a loop, and which results in a cell array of 3x3 matrices:
C = arrayfun(@(s)sqrt(s.matrix_field),S,'UniformOutput',false)
C = 1x2 cell array
{3x3 double} {3x3 double}
celldisp(C)
C{1} = 0.7156 0.3034 0.9401 0.8949 0.9009 0.7890 0.2553 0.7022 0.2558 C{2} = 0.5955 0.3100 0.4549 0.9599 0.8806 0.8985 0.4852 0.8184 0.8393
Since that gives you a cell array, it's convenient to put the result in a new field in the original structure array, if that's ultimately what you want:
[S.sqrt_matrix_field] = C{:}
S = 1x2 struct array with fields:
matrix_field other_field sqrt_matrix_field
S(1).sqrt_matrix_field
ans = 3×3
0.7156 0.3034 0.9401 0.8949 0.9009 0.7890 0.2553 0.7022 0.2558
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
S(2).sqrt_matrix_field
ans = 3×3
0.5955 0.3100 0.4549 0.9599 0.8806 0.8985 0.4852 0.8184 0.8393
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Both of those approaches take the square root of each element of each matrix. Since you mentioned taking the square root of each row of each matrix, I'll make a guess at what that means (squaring each element, summing across each row, and taking the square root of that), and show it using both approches.
First the concatenation approach:
M = sqrt(sum(cat(3,S.matrix_field).^2,2));
disp(M)
(:,:,1) = 1.0256 1.2990 0.5017 (:,:,2) = 0.4217 1.4498 1.0001
It may be convenient to permute that 3x1xN array into a 3xN matrix:
M = permute(M,[1 3 2])
M = 3×2
1.0256 0.4217 1.2990 1.4498 0.5017 1.0001
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
And the arrayfun approach:
C = arrayfun(@(s)sqrt(sum(s.matrix_field.^2,2)),S,'UniformOutput',false)
C = 1x2 cell array
{3x1 double} {3x1 double}
celldisp(C)
C{1} = 1.0256 1.2990 0.5017 C{2} = 0.4217 1.4498 1.0001
And putting those results into the original structure array:
[S.sqrt_matrix_field] = C{:}
S = 1x2 struct array with fields:
matrix_field other_field sqrt_matrix_field
S(1).sqrt_matrix_field
ans = 3×1
1.0256 1.2990 0.5017
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
S(2).sqrt_matrix_field
ans = 3×1
0.4217 1.4498 1.0001
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
You could also concatenate the contents of each cell of C together to form a 3xN matrix:
M = [C{:}]
M = 3×2
1.0256 0.4217 1.2990 1.4498 0.5017 1.0001
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
but if that's the form of the result you need, it's better to skip the cell array entirely and use the concatenation approach.

Categorías

Productos

Versión

R2024a

Preguntada:

el 30 de Sept. de 2024

Respondida:

el 30 de Sept. de 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by