Structures within fields - matlab

s = struct('field1',...
{
struct('a',num2cell(0 + 4*rand(5,1)),'b',num2cell(0 + 4*rand(5,1)),'c',0);...
struct('a',num2cell(0 + 4*rand(5,1)),'b',num2cell(0 + 4*rand(5,1)),'c',0)...
},...
'field2',...
{
struct('a',num2cell(0 + 4*rand(5,1)),'b',num2cell(0 + 4*rand(5,1)),'c',0);...
struct('a',num2cell(0 + 4*rand(5,1)),'b',num2cell(0 + 4*rand(5,1)),'c',0)...
}...
);
How can I loop over structures in each field to avoid listing every structure within a field?

How about
arrayfun( #( w ) structfun( #( x ) arrayfun( #( y ) structfun( #( z ) disp( z ), y ), x ), w ), s )
You can replace disp with whatever function you wish to apply...

Related

cp949 error occurred while using smop. how do i solve it?

I searched for smop cp949 on stackoverflow, but didn't get any results, so I'm posting a question.
Traceback (most recent call last):
File "C:\Users\avern.conda\envs\ML\lib\site-packages\smop\main.py", line 58, in main
buf = open(options.filename).read()
UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 2: illegal multibyte sequence
Errors: 1
clc; clear; close all;
refPath = 'D:\220119 Stroke Segmentation_transUnet\Walin\phoresults_CharSeg'; %'./[1] NeungUK';
savPath = 'D:\220104 Stroke Segmentation\wallin\Pho\classifiedChar3'; %./[3-5] Classification results(nuk)';
refPath = 'D:\programming\Stroke segmentation\TransUNet\data\sukbo_06_300\seg_chrpho2';
savPath = 'D:\programming\Stroke segmentation\TransUNet\data\sukbo_06_300\cls_chrpho3';
refPath = 'D:\programming\Stroke segmentation\TransUNet\data\sukbo_06_300\seg_chrpho2';
savPath = 'D:\programming\Stroke segmentation\TransUNet\data\sukbo_06_300\cls_chrpho3';
refPath = 'D:\programming\Stroke segmentation\TransUNet\data\neungumgyoung_08_600\seg_chrpho';
savPath = 'D:\programming\Stroke segmentation\TransUNet\data\neungumgyoung_08_600\cls_chrpho';
load('net_checkpoint_220124_jamo_ep20.mat','net')
dirImage = dir( fullfile( refPath, '*.png' ));
group_labels = [];
jaumCode = string([ '1100';'1101';'1102';'1103';'1104';'1105';'1106';'1107';'1108';'1109';'110A';...
'110B';'110C';'110D';'110E';'110F';'1110';'1111';'1112';'1115';'111A';'111D';'1120';...
'1121';'1122';'1123';'1127';'112B';'112D';'112F';'1132';'1140';'1145';'1147';'114C';...
'1158';'1159';'115B';'115C';'115D';'11B0';'11B1';'11B2';'11B3';'11B5';'11DD' ]);
moumCode = string([ '11A1';'116A';'116B';'116C';'116D';'116E';'116F';'119E';'1161';'1162';'1163';...
'1165';'1166';'1167';'1168';'1169';'1170';'1171';'1172';'1173';'1174';'1175';'1188';...
'1191';'1192';'1194';'D7C4';'D7C5' ]);
mkdir( fullfile( savPath, 'fail' ));
%%
for n = 1 : size( dirImage, 1 )
[ ~, name, ~ ] = fileparts( fullfile(refPath, dirImage(n).name ));
file = fullfile( dirImage(n).folder, dirImage(n).name );
img = imread( file );
initPho = img( :, :, 2 ) | img( :, :, 3 );
midPho = img( :, :, 1 ) | img( :, :, 3 );
finPho = img( :, :, 1 ) | img( :, :, 2 );
initPho = resize64_Pho(initPho);
midPho = resize64_Pho(midPho);
finPho = resize64_Pho(finPho);
initPred = classify(net, initPho);
midPred = classify(net, midPho);
finPred = classify(net, finPho);
label = join( string([ initPred, midPred, finPred ]), "" );
savdir = fullfile( savPath, label );
ja_Idx1 = find(moumCode == string(initPred));
ja_Idx2 = find(moumCode == string(finPred));
mo_Idx = find(jaumCode == string(midPred));
if ~isempty(ja_Idx1) || ~isempty(ja_Idx2) || ~isempty(mo_Idx)
imwrite( img, fullfile( savPath, 'fail', join([ name '.png' ],"" )), 'png')
else
if any( strcmp( label, group_labels ))
imwrite( img, fullfile( savdir, join([ name '.png' ],"" )), 'png' );
else
assert( ~exist( fullfile( savPath, label ), 'dir' ))
mkdir( fullfile( savPath, label ));
imwrite( img, fullfile( savdir, join([ name '.png' ],"" )), 'png' );
group_labels = vertcat( group_labels, label );
end
end
label = [];
if mod(n,1000)
continue
end
disp([num2str(n)])
end

Powershell is there an easy way to covert an int 5 to a string five or 68 to sixty eight?

I'm trying to figure out if there is an easy way to convert numbers into words take 9 and convert it to nine.
There is an excellent library for .NET called Humanizer that can do exactly this. I haven't tried this yet, but it looks like there is a PowerShell wrapper for it. I suspect this will do exactly what you need.
This has been asked about .NET/C#; you could put this in a class and use Add-Type in powershell to make this work.
.NET convert number to string representation (1 to one, 2 to two, etc...)
Maybe something like this (untested):
$class = #"
public class Num2Word
{
public static string NumberToText( int n)
{
if ( n < 0 )
return "Minus " + NumberToText(-n);
else if ( n == 0 )
return "";
else if ( n <= 19 )
return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"}[n-1] + " ";
else if ( n <= 99 )
return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}[n / 10 - 2] + " " + NumberToText(n % 10);
else if ( n <= 199 )
return "One Hundred " + NumberToText(n % 100);
else if ( n <= 999 )
return NumberToText(n / 100) + "Hundreds " + NumberToText(n % 100);
else if ( n <= 1999 )
return "One Thousand " + NumberToText(n % 1000);
else if ( n <= 999999 )
return NumberToText(n / 1000) + "Thousands " + NumberToText(n % 1000);
else if ( n <= 1999999 )
return "One Million " + NumberToText(n % 1000000);
else if ( n <= 999999999)
return NumberToText(n / 1000000) + "Millions " + NumberToText(n % 1000000);
else if ( n <= 1999999999 )
return "One Billion " + NumberToText(n % 1000000000);
else
return NumberToText(n / 1000000000) + "Billions " + NumberToText(n % 1000000000);
}
}
#"
Add-Type -TypeDefinition $class
[Num2Word]::NumberToText(555)
There's no reason you couldn't write this as pure powershell, but this was already written!

Matlab name assignment

I am trying to decrease some big chucks of matlab code i had from a while ago, and was hoping to get them a bit more "clean".
The VarName2,VarName3,VarName4 ...etc are provide by measured data and i will know what they are always going to be thus i gave me the name A,B ,C , the think i want changed though is the first part of the name, so every time i run the .m file I will use the input('') option
where as fname = 'SWAN' and A, B , C are the second part of the name and they are constant.
fname = input ('enter name')
fname_A = VarName2
fname_B = VarName3
fname_C = VarName4
and want to be getting
SWAN_A = VarName2
SWAN_B = VarName3
SWAN_C = VarName4
thank you
Following your advices I been trying the structure construction
S.name = input ('enter name of the data ".." ==')
S.A = A;
S.A(1,:)=[];
S.B = B;
S.B(1,:)=[];
S.C = C;
S.C(1,:)=[];
S.D = D;
S.D(1,:)=[];
S.E = E;
S.E(1,:)=[];
may i ask if i can also have an input thing command so i can change the name of the structure?
Precede the script with S='west' and then do
'S'.name = input ('enter name of the data ".." ==')
S.A = A;
Here is how I would probably store the information that you are handling:
S.name = input ('enter name')
S.A = VarName2
S.B = VarName3
S.C = VarName4
And if you want to do it a few times:
for t=3:-1:1
S(t).name = input ('enter name')
S(t).A = VarName2
S(t).B = VarName3
S(t).C = VarName4
end
In this way you could now find the struct named 'swan':
idx = strcmpi({S.name},'SWAN')
you can use eval
eval( sprintf('%s_A = VarName2;', fname ) );
eval( sprintf('%s_B = VarName3;', fname ) );
eval( sprintf('%s_C = VarName4;', fname ) );
Note that the use of eval is not recommended.
One alternative option may be to use struct with dynamic field names:
A.( fname ) = VarName2;
B.( fname ) = VarName3;
C.( fname ) = VarName4;
Now you have three structs (A, B and C) with A.SWAN equal to VarName2, B.SWAN equal to VarName3 etc.

FileMaker Divide by Zero Error

I have a Calculation field in my Results table that will calculate the coursework_percent based on a student's submission of classwork, homework, quiz, project and participation. The code for the Calculation field is this:
Sum ( Coursework_Results_Classwork::mark ) / If ( Sum ( Coursework_CR_Classwork::max_mark ) ≠ 0 ; Sum ( Coursework_CR_Classwork::max_mark ) - Sum ( Coursework_Results_Classwork::reduce_max ) ; 1 ) * Coursework_Weighting::classwork_w
+
Sum ( Coursework_Results_Homework::mark ) / If ( Sum ( Coursework_CR_Homework::max_mark ) ≠ 0 ; Sum ( Coursework_CR_Homework::max_mark ) - Sum ( Coursework_Results_Homework::reduce_max ) ; 1 ) * Coursework_Weighting::homework_w
+
Sum ( Coursework_Results_Quiz::mark ) / If ( Sum ( Coursework_CR_Quiz::max_mark ) ≠ 0 ; Sum ( Coursework_CR_Quiz::max_mark ) - Sum ( Coursework_Results_Quiz::reduce_max ) ; 1 ) * Coursework_Weighting::quiz_w
+
Sum ( Coursework_Results_Project::mark ) / If ( Sum ( Coursework_CR_Project::max_mark ) ≠ 0 ; Sum ( Coursework_CR_Project::max_mark ) - Sum ( Coursework_Results_Project::reduce_max ) ; 1 ) * Coursework_Weighting::project_w
+
Sum ( Coursework_Results_Participation::mark ) / If ( Sum ( Coursework_CR_Participation::max_mark ) ≠ 0 ; Sum ( Coursework_CR_Participation::max_mark ) - Sum ( Coursework_Results_Participation::reduce_max ) ) * Coursework_Weighting::participation_w
The idea behind the code is this:
If a student did not submit a coursework due to valid reason, he should not be penalised. Hence, his maximum mark should be adjusted accordingly. I used reduce_max to reduce his otherwise maximum possible score.
My bug is this:
If a particular category (e.g. homework) has only 1 assignment and the student did not submit with valid reason(hence an empty field), the calculated field will have a division by zero error. I cannot use a zero because zero is used for non-submission without valid reason. I suspect that the bug lies in my If condition testing for ≠ 0. An empty field is not considered a zero.
Can someone help me out? Thanks.
I amended pft's answer to solve my problem. The bug was not really due to empty field. Instead, it occurs when I use reduce_max such that the maximum of the coursework becomes zero. My solution is this:
Let ([
sumOfClasswork = Sum ( Coursework_Results_Classwork::mark );
sumOfHomework = Sum ( Coursework_Results_Homework::mark );
sumOfQuiz = Sum ( Coursework_Results_Quiz::mark );
sumOfProject = Sum ( Coursework_Results_Project::mark );
sumOfParticipation = Sum ( Coursework_Results_Participation::mark );
classworkMax = Sum ( Coursework_CR_Classwork::max_mark );
homeworkMax = Sum ( Coursework_CR_Homework::max_mark );
quizMax = Sum ( Coursework_CR_Quiz::max_mark );
projectMax = Sum ( Coursework_CR_Project::max_mark );
participationMax = Sum ( Coursework_CR_Participation::max_mark );
classworkReductions = Sum ( Coursework_Results_Classwork::reduce_max );
homeworkReductions = Sum ( Coursework_Results_Homework::reduce_max );
quizReductions = Sum ( Coursework_Results_Quiz::reduce_max );
projectReductions = Sum ( Coursework_Results_Project::reduce_max );
participationReductions = Sum ( Coursework_Results_Participation::reduce_max );
// if coursework maximum after reduction is zero, 1 is returned to avoid a division by zero error
classworkRedMax = If ( classworkMax - classworkReductions <> 0 ; classworkMax - classworkReductions ; 1 );
homeworkRedMax = If ( homeworkMax - homeworkReductions <> 0 ; homeworkMax - homeworkReductions ; 1 );
quizRedMax = If ( quizMax - quizReductions <> 0 ; quizMax - quizReductions ; 1 );
projectRedMax = If ( projectMax - projectReductions <> 0 ; projectMax - projectReductions ; 1 );
participationRedMax = If ( participationMax - participationReductions <> 0 ; participationMax - participationReductions ; 1 );
classworkWeight = Coursework_Weighting::classwork_w;
homeworkWeight = Coursework_Weighting::homework_w;
quizWeight = Coursework_Weighting::quiz_w;
projectWeight = Coursework_Weighting::project_w;
participationWeight = Coursework_Weighting::participation_w
];
// finally the computation of coursework ;)
sumOfClasswork / classworkRedMax * classworkWeight
+
sumOfHomework / homeworkRedMax * homeworkWeight
+
sumOfQuiz / quizRedMax * quizWeight
+
sumOfProject / projectRedMax * projectWeight
+
sumOfParticipation / participationRedMax * participationWeight
)
I believe the IsEmpty function should help you out here. If I understand your intention correctly, you could use this code segment:
Let ([
sumOfMarks = Sum ( Coursework_Results_Classwork::mark );
sumOfMaxs = Sum ( Coursework_CR_Classwork::max_mark );
sumOfReductions = Sum ( Coursework_Results_Classwork::reduce_max );
firstMax = Coursework_CR_Classwork::max_mark;
theWeight = Coursework_Weighting::classwork_w
];
Case (
// The case where the student has at least one valid,
// positively-scored assignment
sumOfMaxs > 0 ; sumOfMarks / (sumOfMaxs - sumOfReductions) ;
// The case where there is only one related record for max_mark
// and it is empty
IsEmpty ( firstMax ) ; 1
) * theWeight
)

How can I create combinations of several lists without hardcoding loops?

I have data that looks like this:
my #homopol = (
["T","C","CC","G"], # part1
["T","TT","C","G","A"], #part2
["C","CCC","G"], #part3 ...upto part K=~50
);
my #prob = ([1.00,0.63,0.002,1.00,0.83],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02]);
# Note also that the dimension of #homopol is always exactly the same with #prob.
# Although number of elements can differ from 'part' to 'part'.
What I want to do is to
Generate all combinations of elements in part1 through out partK
Find the product of the corresponding elements in #prob.
Hence at the end we hope to get this output:
T-T-C 1 x 0.72 x 1 = 0.720
T-T-CCC 1 x 0.72 x 0.97 = 0.698
T-T-G 1 x 0.72 x 0.02 = 0.014
...
G-G-G 1 x 0.85 x 0.02 = 0.017
G-A-C 1 x 1 x 1 = 1.000
G-A-CCC 1 x 1 x 0.97 = 0.970
G-A-G 1 x 1 x 0.02 = 0.020
The problem is that the following code of mine does that by hardcoding
the loops. Since the number of parts of #homopol is can be varied and large
(e.g. ~K=50), we need a flexible and compact way to get the same result. Is there any?
I was thinking to use Algorithm::Loops, but not sure how to achieve that.
use strict;
use Data::Dumper;
use Carp;
my #homopol = (["T","C","CC","G"],
["T","TT","C","G","A"],
["C","CCC","G"]);
my #prob = ([1.00,0.63,0.002,1.00,0.83],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02]);
my $i_of_part1 = -1;
foreach my $base_part1 ( #{ $homopol[0] } ) {
$i_of_part1++;
my $probpart1 = $prob[0]->[$i_of_part1];
my $i_of_part2 =-1;
foreach my $base_part2 ( #{ $homopol[1] } ) {
$i_of_part2++;
my $probpart2 = $prob[1]->[$i_of_part2];
my $i_of_part3 = -1;
foreach my $base_part3 ( #{ $homopol[2] } ) {
$i_of_part3++;
my $probpart3 = $prob[2]->[$i_of_part3];
my $nstr = $base_part1."".$base_part2."".$base_part3;
my $prob_prod = sprintf("%.3f",$probpart1 * $probpart2 *$probpart3);
print "$base_part1-$base_part2-$base_part3 \t";
print "$probpart1 x $probpart2 x $probpart3 = $prob_prod\n";
}
}
}
I would recommend Set::CrossProduct, which will create an iterator to yield the cross product of all of your sets. Because it uses an iterator, it does not need to generate every combination in advance; rather, it yields each one on demand.
use strict;
use warnings;
use Set::CrossProduct;
my #homopol = (
[qw(T C CC G)],
[qw(T TT C G A)],
[qw(C CCC G)],
);
my #prob = (
[1.00,0.63,0.002,1.00],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02],
);
# Prepare by storing the data in a list of lists of pairs.
my #combined;
for my $i (0 .. $#homopol){
push #combined, [];
push #{$combined[-1]}, [$homopol[$i][$_], $prob[$i][$_]]
for 0 .. #{$homopol[$i]} - 1;
};
my $iterator = Set::CrossProduct->new([ #combined ]);
while( my $tuple = $iterator->get ){
my #h = map { $_->[0] } #$tuple;
my #p = map { $_->[1] } #$tuple;
my $product = 1;
$product *= $_ for #p;
print join('-', #h), ' ', join(' x ', #p), ' = ', $product, "\n";
}
A solution using Algorithm::Loops without changing the input data would look something like:
use Algorithm::Loops;
# Turns ([a, b, c], [d, e], ...) into ([0, 1, 2], [0, 1], ...)
my #lists_of_indices = map { [ 0 .. #$_ ] } #homopol;
NestedLoops( [ #lists_of_indices ], sub {
my #indices = #_;
my $prob_prod = 1; # Multiplicative identity
my #base_string;
my #prob_string;
for my $n (0 .. $#indices) {
push #base_string, $hompol[$n][ $indices[$n] ];
push #prob_string, sprintf("%.3f", $prob[$n][ $indices[$n] ]);
$prob_prod *= $prob[$n][ $indices[$n] ];
}
print join "-", #base_string; print "\t";
print join "x", #prob_string; print " = ";
printf "%.3f\n", $prob_prod;
});
But I think that you could actually make the code clearer by changing the structure to one more like
[
{ T => 1.00, C => 0.63, CC => 0.002, G => 0.83 },
{ T => 0.72, TT => 0.03, ... },
...
]
because without the parallel data structures you can simply iterate over the available base sequences, instead of iterating over indices and then looking up those indices in two different places.
Why don't you use recursion? Pass the depth as a parameter and let the function call itself with depth+1 inside the loop.
you could do it by creating an array of indicies the same length as the #homopol array (N say), to keep track of which combination you are looking at. In fact this array is just like a
number in base N, with the elements being the digits. Iterate in the same way as you would write down consectutive numbers in base N, e.g (0 0 0 ... 0), (0 0 0 ... 1), ...,(0 0 0 ... N-1), (0 0 0 ... 1 0), ....
Approach 1: Calculation from indices
Compute the product of lengths in homopol (length1 * length2 * ... * lengthN). Then, iterate i from zero to the product. Now, the indices you want are i % length1, (i / length1)%length2, (i / length1 / length2) % length3, ...
Approach 2: Recursion
I got beaten to it, see nikie's answer. :-)