Convert MyList(,) of Object to String array with LINQ - arrays

I have a little problem with the performance of one of my applications, basically:
An external system gives me a big structure as an Object(,).
This structure only has an column per row.
MyData(0,0) = 'COL1-ROW1 | COL2-ROW1 | COL3-ROW1'
MyData(1,0) = 'COL1-ROW2 | COL2-ROW2 | COL3-ROW2'
MyData(2,0) = 'COL1-ROW3 | COL2-ROW3 | COL3-ROW3'
MyData(3,0) = 'COL1-ROW4 | COL2-ROW4 | COL3-ROW4'
MyData(0,1) ' Doesn't exists.
There are some method in LINQ to convert this structure to an one dimensional array of strings?
It would be awesome if you could divide by columns, given a specific character.
Something like this:
NewData(0,0) = COL1-ROW1
NewData(0,1) = COL2-ROW1
NewData(0,2) = COL3-ROW1
NewData(1,0) = COL1-ROW2
...
NewData(3,2) = COL3-ROW3

Seems I found the answer from myself; here my solution:
Dim vMyData(1000, 0) As Object
For x = 0 To 1000
vMyData(x, 0) = String.Format("ROW{0}COL1|ROW{0}COL2|ROW{0}COL3|ROW{0}COL4", x)
Next
Dim vQuery = From TempResult In vMyData
Select Value = TempResult.ToString.Split("|")
Dim vMyNewArray As New ArrayList(vQuery.ToArray)
Now; exists some method to trim each value of the Split("|")?
[UPDATE TO THE PREVIOUS QUESTION]:
From TempResult In vMyData Select Value = Array.ConvertAll(TempResult.ToString.Split("|"), Function(vVal) vVal.ToString.Trim)

Related

Create array of "deep" struct (scalar) fields

How can I collapse the values of "deep" struct fields into arrays by just indexing?
In the example below, I can only do it for the "top-most" level, and for "deeper" levels I get the error:
"Expected one output from a curly brace or dot indexing expression, but there were XXX results."
The only workaround I found so far is to unfold the operation into several steps, but the deeper the structure the uglier this gets...
clc; clear variables;
% Dummy data
my_struc.points(1).fieldA = 100;
my_struc.points(2).fieldA = 200;
my_struc.points(3).fieldA = 300;
my_struc.points(1).fieldB.subfieldM = 10;
my_struc.points(2).fieldB.subfieldM = 20;
my_struc.points(3).fieldB.subfieldM = 30;
my_struc.points(1).fieldC.subfieldN.subsubfieldZ = 1;
my_struc.points(2).fieldC.subfieldN.subsubfieldZ = 2;
my_struc.points(3).fieldC.subfieldN.subsubfieldZ = 3;
my_struc.info = 'Note my_struc has other fields besides "points"';
% Get all fieldA values by just indexing (this works):
all_fieldA_values = [my_struc.points(:).fieldA]
% Get all subfieldM values by just indexing (doesn't work):
% all_subfieldM_values = [my_struc.points(:).fieldB.subfieldM]
% Ugly workaround:
temp_array_of_structs = [my_struc.points(:).fieldB];
all_subfieldM_values = [temp_array_of_structs.subfieldM]
% Get all subsubfieldZ values by just indexing (doesn't work):
% all_subsubfieldZ_values = [my_struc.points(:).fieldC.subfieldN.subsubfieldZ]
% Ugly workaround:
temp_array_of_structs1 = [my_struc.points(:).fieldC];
temp_array_of_structs2 = [temp_array_of_structs1.subfieldN];
all_subsubfieldZ_values = [temp_array_of_structs2.subsubfieldZ]
Output:
all_fieldA_values =
100 200 300
all_subfieldM_values =
10 20 30
all_subsubfieldZ_values =
1 2 3
Thanks for any help!
You can use arrayfun to have acces to each individual 'point', and then acces its data. This will return an array with the same dimensions as my_struc.points:
all_subfieldM_values = arrayfun(#(in) in.fieldB.subfieldM, my_struc.points)
all_subsubfieldZ_values = arrayfun(#(in) in.fieldC.subfieldN.subsubfieldZ, my_struc.points)
Not optimal, but at least it's one line.

How to loop through table based on unique date in MATLAB

I have this table named BondData which contains the following:
Settlement Maturity Price Coupon
8/27/2016 1/12/2017 106.901 9.250
8/27/2019 1/27/2017 104.79 7.000
8/28/2016 3/30/2017 106.144 7.500
8/28/2016 4/27/2017 105.847 7.000
8/29/2016 9/4/2017 110.779 9.125
For each day in this table, I am about to perform a certain task which is to assign several values to a variable and perform necessary computations. The logic is like:
do while Settlement is the same
m_settle=current_row_settlement_value
m_maturity=current_row_maturity_value
and so on...
my_computation_here...
end
It's like I wanted to loop through my settlement dates and perform task for as long as the date is the same.
EDIT: Just to clarify my issue, I am implementing Yield Curve fitting using Nelson-Siegel and Svensson models.Here are my codes so far:
function NS_SV_Models()
load bondsdata
BondData=table(Settlement,Maturity,Price,Coupon);
BondData.Settlement = categorical(BondData.Settlement);
Settlements = categories(BondData.Settlement); % get all unique Settlement
for k = 1:numel(Settlements)
rows = BondData.Settlement==Settlements(k);
Bonds.Settle = Settlements(k); % current_row_settlement_value
Bonds.Maturity = BondData.Maturity(rows); % current_row_maturity_value
Bonds.Prices=BondData.Price(rows);
Bonds.Coupon=BondData.Coupon(rows);
Settle = Bonds.Settle;
Maturity = Bonds.Maturity;
CleanPrice = Bonds.Prices;
CouponRate = Bonds.Coupon;
Instruments = [Settle Maturity CleanPrice CouponRate];
Yield = bndyield(CleanPrice,CouponRate,Settle,Maturity);
NSModel = IRFunctionCurve.fitNelsonSiegel('Zero',Settlements(k),Instruments);
SVModel = IRFunctionCurve.fitSvensson('Zero',Settlements(k),Instruments);
NSModel.Parameters
SVModel.Parameters
end
end
Again, my main objective is to get each model's parameters (beta0, beta1, beta2, etc.) on a per day basis. I am getting an error in Instruments = [Settle Maturity CleanPrice CouponRate]; because Settle contains only one record (8/27/2016), it's suppose to have two since there are two rows for this date. Also, I noticed that Maturity, CleanPrice and CouponRate contains all records. They should only contain respective data for each day.
Hope I made my issue clearer now. By the way, I am using MATLAB R2015a.
Use categorical array. Here is your function (without its' headline, and all rows I can't run are commented):
BondData = table(datetime(Settlement),datetime(Maturity),Price,Coupon,...
'VariableNames',{'Settlement','Maturity','Price','Coupon'});
BondData.Settlement = categorical(BondData.Settlement);
Settlements = categories(BondData.Settlement); % get all unique Settlement
for k = 1:numel(Settlements)
rows = BondData.Settlement==Settlements(k);
Settle = BondData.Settlement(rows); % current_row_settlement_value
Mature = BondData.Maturity(rows); % current_row_maturity_value
CleanPrice = BondData.Price(rows);
CouponRate = BondData.Coupon(rows);
Instruments = [datenum(char(Settle)) datenum(char(Mature))...
CleanPrice CouponRate];
% Yield = bndyield(CleanPrice,CouponRate,Settle,Mature);
%
% NSModel = IRFunctionCurve.fitNelsonSiegel('Zero',Settlements(k),Instruments);
% SVModel = IRFunctionCurve.fitSvensson('Zero',Settlements(k),Instruments);
%
% NSModel.Parameters
% SVModel.Parameters
end
Keep in mind the following:
You cannot concat different types of variables as you try to do in: Instruments = [Settle Maturity CleanPrice CouponRate];
There is no need in the structure Bond, you don't use it (e.g. Settle = Bonds.Settle;).
Use the relevant functions to convert between a datetime object and string or numbers. For instance, in the code above: datenum(char(Settle)). I don't know what kind of input you need to pass to the following functions.

How to use a self made Type in F#?

I made a type, but I don't know how to use it properly and I don't found any solution on google.
type Sample =
{
TrackPosition : int
TubePosition : int
Barcode : string
}
let arraySamples = Array.create Scenario.Samples.NumberOfSamples **Sample**
BarcodeGenerieren.Samples.Sample
let mutable trackPosition = Scenario.Samples.StartTrackPositions
let mutable index = 1
for i in 1 .. Scenario.Samples.NumberOfSamples do
let randomNumber = System.Random().Next(0,9999)
if index > 24 then
trackPosition <- trackPosition + 1
index <- 1
arraySamples.[index] <- **new Sample{TrackPosition= trackPosition, TubePosition = index, Barcode = sprintf "100%s%06d" ((trackPosition + 1) - Scenario.Samples.StartTrackPositions) randomNumber}**
So my question is, what should I changed so that it works, when I will give the type of the array and when I will give the sample with data to the array?
You have created what is referred to as a record type. You can initialise it with the following syntax
{TrackPosition = 0;TubePosition = 0;Barcode = "string"}
your syntax in the last line is almost correct - it should be
arraySamples.[index] <- Sample{
TrackPosition= trackPosition;
TubePosition = index;
Barcode = sprintf "100%s%06d" ((trackPosition + 1) - Scenario.Samples.StartTrackPositions) randomNumber}
The changes are
Eliminate new
replace , with ;

Matlab: Improving a tree traversal code

I have the structure that is demonstrated below:
I have a database folder which contains brands. Each brand consists of logo and query.
I want to traverse on all the the files (file_1 to file_n) in all the database and perform some operations on them.
I wrote this code:
d = dir(database);
isub = [d(:).isdir];
brandsFolders = {d(isub).name}';
brandsFolders(ismember(brandsFolders,{'.','..'})) = [];
[numberOfBrands not_used]=size(brandsFolders); %holds the number of the brands
for i=1:numberOfBrands
temp=strcat(database, '\');
currentBrand=strcat(temp, brandsFolders(i));
d = dir(currentBrand{1,1});
isub = [d(:).isdir];
logoAndQuery = {d(isub).name}';
logoAndQuery(ismember(logoAndQuery,{'.','..'})) = [];
logo=strcat(currentBrand, '\', logoAndQuery(1));
files=dir(logo{1,1});
[numberOfFiles not_used]=size(files);
for j=1:numberOfFiles
if strcmp(files(j).name, '..')~=1 && strcmp(files(j).name, '.')~=1
%operations on each files(j).name
end
end
end
The code works fine, it traverse on the desired files.
However, the code is little bit ugly and confusing.
I was wondering if I can do it in another better way?
Traversing through a set of directories goes pretty much as you are doing. However imo, there are some things you can do easier / I would do differently:
brandsFolders = dir(database);
brandsFolders( ~[brandsFolders.isdir] | strcmp({brandsFolders.name},'.') | strcmp({brandsFolders.name},'..')) = [];
for ii=1:numel(brandsFolders)
logoAndQuery = dir(fullfile(database,brandsFolders(ii).name));
logoAndQuery( ~[logoAndQuery.isdir] | strcmp({logoAndQuery.name},'.') | strcmp({logoAndQuery.name},'..')) = [];
logo = fullfile(databasecurrentBrand,brandsFolders(ii).name), logoAndQuery(1).name);
files = dir(logo);
files(strcmp({files.name},'.') | strcmp({files.name},'..'))=[];
for jj=1:numel(files)
%operations on each files(j).name
end
end
(This of course only works if you're sure that logoAndQuery(1) will always be the 'logo' directory.)
or alternatively use a subfunction for the dir-querying:
function dirs = getDirs(strPath)
dirs = dir(strPath);
dirnames = {dirs.name};
dirs ( ~[dirs.isdir] | strcmp(dirnames ,'.') | strcmp(dirnames ,'..')) = [];
end
which gives you already some shorter code and gives the following, in which I also assume there are no directories in the 'logo' directories:
brandsFolders = getDirs(database);
for ii=1:numel(brandsFolders)
logoAndQuery = getDirs(fullfile(database,brandsFolders(ii).name));
logo = fullfile(databasecurrentBrand,brandsFolders(ii).name), logoAndQuery(1).name);
files = dir(logo);
files([files.isdir])=[];
for jj=1:numel(files)
%operations on each files(j).name
end
end

MATLAB: Select all of an array EXCEPT in given ranges

I'd like to perform metrics on the contents of an array that do NOT fall within certain ranges.
For example, I have an array with 1000 rows and 2 columns. I'd like to perform a mean() calculation on all the elements in one column (let's say column #2) that don't fall in rows 50-150, 250-300, 400-700 and 900-950.
Thus, the mean should be calculated based on rows 1-49, 151-249, 301-399, 701-899 and 951-1000.
Any ideas how to go about this?
Edit: I should point out that those items which are included will change each time the program is run. Therefore, I can't just hard-code the inclusions in; they need to be worked out based on the exclusions.
How about:
M = rand(1000,2);
idx = setdiff(1:size(M,1), [50:150, 250:300, 400:700, 900:950]);
MM = M(idx,:)
Now apply any function to the filtered matrix:
mean(MM,1)
You can define the exclusion ranges and then use logical addressing:
LowerLimit1 = 1;
UpperLimit1 = 50;
LowerLimit2 = 151;
UpperLimit2 = 249;
LowerLimit3 = 301;
UpperLimit3 = 399;
LowerLimit4 = 701;
UpperLimit4 = 899;
LowerLimit5 = 951;
UpperLimit5 = 1000;
MyVector = MyMatrix(:,2);
MeanValue = mean(MyVector(~(MyVector > LowerLimit1 & MyVector < UpperLimit1) | (MyVector > LowerLimit2 & MyVector < UpperLimit2) | (MyVector > LowerLimit3 & MyVector < UpperLimit3) | (MyVector > LowerLimit4 & MyVector < UpperLimit4) | (MyVector > LowerLimit5 & MyVector < UpperLimit5)));

Resources