Sub-titles for matrix columns in table - matlab

Here's my toy example:
t = table([1,2,3;4,5,6;7,8,9],[10,11,12;13,14,15;16,17,18]);
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
I am wondering if it's possible to assign sub titles to the three columns of every variable, such as {'min', 'mean', 'max'}?

You can put those subtitles within the variables using a cell array like this:
t = table({'min', 'mean', 'max'; 1, 2, 3; 4, 5, 6; 7, 8, 9},...
{'min', 'mean', 'max'; 10, 11, 12; 13, 14, 15; 16, 17, 18});
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'.','obs1', 'obs2', 'obs3'};
%if you don't like dot (.) as a row name, replace it with char(8203) to have nameless row
which will give:
t =
4×2 table
system1 system2
________________________ ________________________
. 'min' 'mean' 'max' 'min' 'mean' 'max'
obs1 [ 1] [ 2] [ 3] [ 10] [ 11] [ 12]
obs2 [ 4] [ 5] [ 6] [ 13] [ 14] [ 15]
obs3 [ 7] [ 8] [ 9] [ 16] [ 17] [ 18]

If you're looking for functional solution (e.g. t.system1.min) You can nest sub-tables for system1 and system2 with {'min', 'mean', 'max'} as Variable Names. Visually it won't be as useful as other solutions.
dat1 = [1,2,3;4,5,6;7,8,9];
dat2 = [10,11,12;13,14,15;16,17,18];
s1 = table(dat1(:,1),dat1(:,2),dat1(:,3));
s2 = table(dat2(:,1),dat2(:,2),dat2(:,3));
s1.Properties.VariableNames = {'min','mean','max'};
s1.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
s2.Properties.VariableNames = {'min','mean','max'};
s2.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
t = table(s1,s2);
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'obs1', 'obs2', 'obs3'};

Related

nvim-treesitter: query for jsdoc description within javascript file

I'm experimenting with a testing regime for my neovim plugin regexplainer. The idea is to put a JSDoc docblock containing the expected output on top of each query.
/**
* #group CaptureGroups
* **0-9** (_>= 0x_)
* capture group 1:
* **0-9**
*/
/\d*(\d)/;
My test file would then iterate through the file, getting each regex from the javascript tree, along with it's expected output from the comment. I could then run my plugin on the regexp and check the output against the comment.
I wrote this function to query the document for comments with regexp following.
function M.get_regexes_with_descriptions()
local log = require'regexplainer.utils'.debug
local query_js = vim.treesitter.query.parse_query('javascript', [[
(comment) #comment
(expression_statement
(regex
(regex_pattern) #regex))
]])
local query_jsdoc = vim.treesitter.query.parse_query('jsdoc', [[
(tag_name) #tag_name
(description) #description
]])
local parser = vim.treesitter.get_parser(0, 'javascript')
local tree, other = unpack(parser:parse())
for id, node, metadata in query_js:iter_captures(tree:root(), 0) do
local name = query_js.captures[id] -- name of the capture in the query
if node:type() == 'comment' then
for cid, cnode, cmetadata in node:iter_children() do
local cname = query_jsdoc.captures[cid] -- name of the capture in the query
log(get_info_on_capture(cid, cnode, cname, cmetadata))
end
end
end
end
I expect this to log the tag name and description nodes from the 'jsdoc' grammar, but i actually get nothing
So how do I "query down" into the embedded JSDoc part of the tree? I tried this query, but got a query: invalid node type at position 10 error when parsing the query:
(comment (description) #desc) #comment
(expression_statement
(regex
(regex_pattern) #regex))
The TSPlayground output for the file in question looks like this:
comment [0, 0] - [5, 3]
tag [1, 3] - [4, 12]
tag_name [1, 3] - [1, 9]
description [1, 10] - [4, 12]
expression_statement [6, 0] - [6, 10]
regex [6, 0] - [6, 9]
pattern: regex_pattern [6, 1] - [6, 8]
term [6, 1] - [6, 8]
character_class_escape [6, 1] - [6, 3]
zero_or_more [6, 3] - [6, 4]
anonymous_capturing_group [6, 4] - [6, 8]
pattern [6, 5] - [6, 7]
term [6, 5] - [6, 7]
character_class_escape [6, 5] - [6, 7]
EDIT: A Workaround
I developed this workaround but it's a bit unsatisfying, I'd prefer to get the comment's contents along with the regexp in a single query
function M.get_regexes_with_descriptions()
local log = require'regexplainer.utils'.debug
local parsers = require "nvim-treesitter.parsers"
local query_js = vim.treesitter.query.parse_query('javascript', [[
(expression_statement
(regex
(regex_pattern) #regex)) #expr
]])
local query_jsdoc = vim.treesitter.query.parse_query('jsdoc', [[
(tag
(tag_name) #tag_name
((description) #description
;; (#eq? #tag_name "example")
))
]])
local parser = parsers.get_parser(0)
local tree = unpack(parser:parse())
local caps = {}
for id, node in query_js:iter_captures(tree:root(), 0) do
local cap = {}
local name = query_js.captures[id] -- name of the capture in the query
log(id, name, ts_utils.get_node_text(node))
if name == 'expr' then
cap.regex = node:named_child('pattern')
cap.comment = node:prev_sibling()
table.insert(caps, cap)
end
end
local results = {}
for _, cap in ipairs(caps) do
local result = {}
result.text = ts_utils.get_node_text(cap.regex)
local comment_str = table.concat(ts_utils.get_node_text(cap.comment), '\n')
local jsdoc_parser = vim.treesitter.get_string_parser(comment_str, 'jsdoc')
local jsdoc_tree = jsdoc_parser:parse()[1]
for id, ch, metadata in query_jsdoc:iter_captures(jsdoc_tree:root()) do
if query_jsdoc.captures[id] == 'description' then
result.description = table.concat(
vim.tbl_map(function(line)
return line:gsub('^%s+%*', '')
end, ts_utils.get_node_text(ch)), '\n')
end
end
table.insert(results, result)
end
return results
end

Swift: How to check intersection with multiple sets?

I have a master set generated by 5 random numbers from 1 to 52; I would like to compare this master set with 13 other sets, each containing 4 numbers between 1 and 52.
Is there a way to check if there are any 2 sets, each containing 2 numbers from the master set?
import UIKit
var firstCard = 0
var secondCard = 0
var thirdCard = 0
var fourthCard = 0
var fifthCard = 0
func generateRandomNumber(_ from:Int, _ to:Int, _ qut:Int?) -> [Int]
{
var myRandomNumbers = [Int]()
var numberOfNumbers = qut
let lower = UInt32(from)
let higher = UInt32(to+1)
if numberOfNumbers == nil || numberOfNumbers! > (to-from) + 1
{
numberOfNumbers = (to-from) + 1
}
while myRandomNumbers.count != numberOfNumbers
{
let myNumber = arc4random_uniform(higher - lower) + lower
if !myRandomNumbers.contains(Int(myNumber))
{
myRandomNumbers.append(Int(myNumber))
}
}
return myRandomNumbers
}
let myArray = generateRandomNumber(1, 53, 5)
firstCard = myArray[0]
secondCard = myArray[1]
thirdCard = myArray[2]
fourthCard = myArray[3]
fifthCard = myArray[4]
let mainSetA = Set([firstCard, secondCard, thirdCard, fourthCard, fifthCard])
let setB: Set = [1, 2, 3, 4]
let setC: Set = [5, 6, 7, 8]
let setD: Set = [9, 10, 11, 12]
let setE: Set = [13, 14, 15, 16]
let setF: Set = [17, 18, 19, 20]
let setG: Set = [21, 22, 23, 24]
let setH: Set = [25, 26, 27, 28]
let setI: Set = [29, 30, 31, 32]
let setJ: Set = [33, 34, 35, 36]
let setK: Set = [37, 38, 39, 40]
let setL: Set = [41, 42, 43, 44]
let setM: Set = [45, 46, 47, 48]
let setN: Set = [49, 50, 51, 52]
no clue what to do next...
Something like this might help:
let mainSet = Set([1, 2, 3, 4])
Here I have three sets out of four that contain at least two items in the main set:
let inputs: [Set<Int>] = [
Set([9, 8, 7, 1]),
Set([9, 8, 1, 2]),
Set([9, 1, 2, 3]),
Set([9, 0, 3, 4])
]
Filter the input sets array, to find any where the intersection between that set and the main set is at least 2:
let matchingSets = inputs.filter {
$0.intersection(mainSet).count >= 2
}

How to pick an element from matrix (list of list in python) based on decision variables (one for row, and one for column) | OR-Tools, Python

I am new to constraint programming and OR-Tools. A brief about the problem. There are 8 positions, for each position I need to decide which move of type A (move_A) and which move of type B (move_B) should be selected such that the value achieved from the combination of the 2 moves (at each position) is maximized. (This is only a part of the bigger problem though). And I want to use AddElement approach to do the sub setting.
Please see the below attempt
from ortools.sat.python import cp_model
model = cp_model.CpModel()
# value achieved from combination of different moves of type A
# (moves_A (rows)) and different moves of type B (moves_B (columns))
# for e.g. 2nd move of type A and 3rd move of type B will give value = 2
value = [
[ -1, 5, 3, 2, 2],
[ 2, 4, 2, -1, 1],
[ 4, 4, 0, -1, 2],
[ 5, 1, -1, 2, 2],
[ 0, 0, 0, 0, 0],
[ 2, 1, 1, 2, 0]
]
# 6 moves of type A
num_moves_A = len(value)
# 5 moves of type B
num_moves_B = len(value[0])
num_positions = 8
type_move_A_position = [model.NewIntVar(0, num_moves_A - 1, f"move_A[{i}]") for i in range(num_positions)]
type_move_B_position = [model.NewIntVar(0, num_moves_B - 1, f"move_B[{i}]") for i in range(num_positions)]
value_position = [model.NewIntVar(0, 10, f"value_position[{i}]") for i in range(num_positions)]
# I am getting an error when I run the below
objective_terms = []
for i in range(num_positions):
model.AddElement(type_move_B_position[i], value[type_move_A_position[i]], value_position[i])
objective_terms.append(value_position[i])
The error is as follows:
Traceback (most recent call last):
File "<ipython-input-65-3696379ce410>", line 3, in <module>
model.AddElement(type_move_B_position[i], value[type_move_A_position[i]], value_position[i])
TypeError: list indices must be integers or slices, not IntVar
In MiniZinc the below code would have worked
var int: obj = sum(i in 1..num_positions ) (value [type_move_A_position[i], type_move_B_position[i]])
I know in OR-Tools we will have to create some intermediary variables to store results first, so the above approach of minizinc will not work. But I am struggling to do so.
I can always create a 2 matrix of binary binary variables one for num_moves_A * num_positions and the other for num_moves_B * num_positions, add re;evant constraints and achieve the purpose
But I want to learn how to do the same thing via AddElement constraint
Any help on how to re-write the AddElement snippet is highly appreciated. Thanks.
AddElement is 1D only.
The way it is translated from minizinc to CP-SAT is to create an intermediate variable p == index1 * max(index2) + index2 and use it in an element constraint with a flattened matrix.
Following Laurent's suggestion (using AddElement constraint):
from ortools.sat.python import cp_model
model = cp_model.CpModel()
# value achieved from combination of different moves of type A
# (moves_A (rows)) and different moves of type B (moves_B (columns))
# for e.g. 2 move of type A and 3 move of type B will give value = 2
value = [
[-1, 5, 3, 2, 2],
[2, 4, 2, -1, 1],
[4, 4, 0, -1, 2],
[5, 1, -1, 2, 2],
[0, 0, 0, 0, 0],
[2, 1, 1, 2, 0],
]
min_value = min([min(i) for i in value])
max_value = max([max(i) for i in value])
# 6 moves of type A
num_moves_A = len(value)
# 5 moves of type B
num_moves_B = len(value[0])
# number of positions
num_positions = 5
# flattened matrix of values
value_flat = [value[i][j] for i in range(num_moves_A) for j in range(num_moves_B)]
# flattened indices
flatten_indices = [
index1 * len(value[0]) + index2
for index1 in range(len(value))
for index2 in range(len(value[0]))
]
type_move_A_position = [
model.NewIntVar(0, num_moves_A - 1, f"move_A[{i}]") for i in range(num_positions)
]
model.AddAllDifferent(type_move_A_position)
type_move_B_position = [
model.NewIntVar(0, num_moves_B - 1, f"move_B[{i}]") for i in range(num_positions)
]
model.AddAllDifferent(type_move_B_position)
# below intermediate decision variable is created which
# will store index corresponding to the selected move of type A and
# move of type B for each position
# this will act as index in the AddElement constraint
flatten_index_num = [
model.NewIntVar(0, len(flatten_indices), f"flatten_index_num[{i}]")
for i in range(num_positions)
]
# another intermediate decision variable is created which
# will store value corresponding to the selected move of type A and
# move of type B for each position
# this will act as the target in the AddElement constraint
value_position_index_num = [
model.NewIntVar(min_value, max_value, f"value_position_index_num[{i}]")
for i in range(num_positions)
]
objective_terms = []
for i in range(num_positions):
model.Add(
flatten_index_num[i]
== (type_move_A_position[i] * len(value[0])) + type_move_B_position[i]
)
model.AddElement(flatten_index_num[i], value_flat, value_position_index_num[i])
objective_terms.append(value_position_index_num[i])
model.Maximize(sum(objective_terms))
# Solve
solver = cp_model.CpSolver()
status = solver.Solve(model)
solver.ObjectiveValue()
for i in range(num_positions):
print(
str(i)
+ "--"
+ str(solver.Value(type_move_A_position[i]))
+ "--"
+ str(solver.Value(type_move_B_position[i]))
+ "--"
+ str(solver.Value(value_position_index_num[i]))
)
The below version uses AddAllowedAssignments constraint to achieve the same purpose (per Laurent's alternate approach) :
from ortools.sat.python import cp_model
model = cp_model.CpModel()
# value achieved from combination of different moves of type A
# (moves_A (rows)) and different moves of type B (moves_B (columns))
# for e.g. 2 move of type A and 3 move of type B will give value = 2
value = [
[-1, 5, 3, 2, 2],
[2, 4, 2, -1, 1],
[4, 4, 0, -1, 2],
[5, 1, -1, 2, 2],
[0, 0, 0, 0, 0],
[2, 1, 1, 2, 0],
]
min_value = min([min(i) for i in value])
max_value = max([max(i) for i in value])
# 6 moves of type A
num_moves_A = len(value)
# 5 moves of type B
num_moves_B = len(value[0])
# number of positions
num_positions = 5
type_move_A_position = [
model.NewIntVar(0, num_moves_A - 1, f"move_A[{i}]") for i in range(num_positions)
]
model.AddAllDifferent(type_move_A_position)
type_move_B_position = [
model.NewIntVar(0, num_moves_B - 1, f"move_B[{i}]") for i in range(num_positions)
]
model.AddAllDifferent(type_move_B_position)
value_position = [
model.NewIntVar(min_value, max_value, f"value_position[{i}]")
for i in range(num_positions)
]
tuples_list = []
for i in range(num_moves_A):
for j in range(num_moves_B):
tuples_list.append((i, j, value[i][j]))
for i in range(num_positions):
model.AddAllowedAssignments(
[type_move_A_position[i], type_move_B_position[i], value_position[i]],
tuples_list,
)
model.Maximize(sum(value_position))
# Solve
solver = cp_model.CpSolver()
status = solver.Solve(model)
solver.ObjectiveValue()
for i in range(num_positions):
print(
str(i)
+ "--"
+ str(solver.Value(type_move_A_position[i]))
+ "--"
+ str(solver.Value(type_move_B_position[i]))
+ "--"
+ str(solver.Value(value_position[i]))
)

MATLAB : How to replace numbers in a single column of a cell with corresponding strings?

I have a 50000 * 2 cell with number contents. Now I want to replace the second column which has numbers ranging from 1 to 10 with corresponding strings like 'airplane' for 1, 'automobile' for 2 and so on. What is the most efficient method for this?
I tried first by splitting the second column content to a new cell classes1 and coverted it to strings and tried replacing by applying the code below :
classes1(strcmp('1',classes1))={'airplane'};
classes1(strcmp('2',classes1))={'automobile'};
classes1(strcmp('3',classes1))={'bird'};
classes1(strcmp('4',classes1))={'cat'};
classes1(strcmp('5',classes1))={'deer'};
classes1(strcmp('6',classes1))={'dog'};
classes1(strcmp('7',classes1))={'frog'};
classes1(strcmp('8',classes1))={'horse'};
classes1(strcmp('9',classes1))={'ship'};
classes1(strcmp('10',classes1))={'truck'};
But that was not successfull. It only replaced '10' with 'truck'.
UPDATE : This code will actually work. But in my case strings ' 1' has to be used instead '1' (a space was missing).
Use this to extend to your big case -
%%// Create look up and numeral data cell arrays for demo
LOOKUP_CELL_ARRAY = {'airplane','automobile','chopper'};
IN_CELL_ARRAY = num2cell(round(1+2.*rand(10,2)))
%%// Replace the second column of data cell array with corresponding
%%// strings in the look up array
IN_CELL_ARRAY(:,2)= LOOKUP_CELL_ARRAY(cell2mat(IN_CELL_ARRAY(:,2)))
Output -
IN_CELL_ARRAY =
[2] [2]
[2] [2]
[2] [1]
[2] [2]
[3] [1]
[2] [3]
[1] [1]
[3] [3]
[2] [2]
[2] [3]
IN_CELL_ARRAY =
[2] 'automobile'
[2] 'automobile'
[2] 'airplane'
[2] 'automobile'
[3] 'airplane'
[2] 'chopper'
[1] 'airplane'
[3] 'chopper'
[2] 'automobile'
[2] 'chopper'
You can do it as follows with cellfun:
% replacement strings
R = {'airplane','automobile','bird','cat','deer', ...
'dog','frog','horse','ship','truck'};
% example data
nums = randi(10,100,1);
data(:,1) = num2cell(nums)
data(:,2) = cellstr(num2str(nums))
data =
[ 3] ' 3'
[ 1] ' 1'
[ 1] ' 1'
[ 8] ' 8'
[ 8] ' 8'
[ 8] ' 8'
[ 7] ' 7'
[ 9] ' 9'
[ 1] ' 1'
...
str2double(x) does not care about whether its '01' or '1':
% replicate number strings with strings
data(:,2) = cellfun(#(x) R( str2double(x) ), data(:,2) )
data =
[ 3] 'bird'
[ 1] 'airplane'
[ 1] 'airplane'
[ 8] 'horse'
[ 8] 'horse'
[ 8] 'horse'
[ 7] 'frog'
[ 9] 'ship'
[ 1] 'airplane'
...
You can do it just with indexing:
data = {'aa' 1
'bb' 3
'cc' 2
'dd' 6
'ee' 1
'ff' 5}; %// example data: two-col cell array, 2nd col is numbers
str = {'airplane','automobile','bird','cat','deer', ...
'dog','frog','horse','ship','truck'}; %// replacement strings
data(:,2) = str(vertcat(data{:,2})); %// do the replacing

Extract a single column from a matrix

I have a matrix generated from the program written in Matlab something like this :
'A' 'B' 'C' 'D' 'E'
[ 4] [ 1] [ 0.9837] [ 0.9928] [0.9928]
[ 4] [ 1] [ 0.9995] [ 0.9887] [0.9995]
[ 4] [ 1] [ 0.9982] [ 0.9995] [0.9995]
[ 4] [ 1] [ 0.9959] [ 0.9982] [0.9887]
I am trying to extract the column 'D' without the header 'D'.
I can put into a temporary variable and then extract the column data. But I am wondering, if it could be done in a single step.
Thanks
If your variable is data, then data(2:end,4) should do it.
Edit:
For example:
>> data
data =
'A' 'B' 'C' 'D' 'E'
[4] [1] [0.9837] [0.9928] [0.9928]
[4] [1] [0.9995] [0.9887] [0.9995]
[4] [1] [0.9982] [0.9995] [0.9995]
[4] [1] [0.9959] [0.9982] [0.9887]
>> data(2:end,4) %Extract the data as a cell array
ans =
[0.9928]
[0.9887]
[0.9995]
[0.9982]
>> cell2mat(data(2:end,4)) %Convert to a numeric (typical) array
ans =
0.9928
0.9887
0.9995
0.9982