Bucket prediction given an integer? - algorithm

If I have a dictionary of integers where the value is an array of two integers sorted, with the two values being the largest value, and the smallest value out of k values present in bucket n, how can I predict/estimate which bucket a given number would appear.
An example of said dictionary is:
{
1: [
541247,
14771
],
15: [
9789,
9621
],
22: [
8984,
8923
],
64: [
7278,
7263
],
93: [
6846,
6804
],
126: [
5789,
5765
],
139: [
5484,
5462
],
208: [
4326,
4314
],
285: [
3788,
3783
],
322: [
3634,
3631
],
337: [
3586,
3582
],
356: [
3517,
3513
],
448: [
3232,
3229
],
459: [
3199,
3196
],
539: [
2990,
2989
],
581: [
2891,
2890
],
596: [
2858,
2856
],
640: [
2770,
2768
],
675: [
2704,
2702
],
679: [
2697,
2695
],
686: [
2684,
2682
],
733: [
2602,
2600
],
879: [
2387,
2386
],
961: [
2283,
2282
],
980: [
2261,
2260
],
995: [
2244,
2243
],
1000: [
2238,
2237
],
1169: [
2064,
2063
],
1175: [
2058,
2057
],
1236: [
2005,
2004
],
1259: [
1985,
1984
],
1281: [
1967,
1966
],
1348: [
1913,
1912
],
1424: [
1855,
1855
],
1429: [
1852,
1851
],
1514: [
1796,
1795
],
1564: [
1764,
1764
],
1596: [
1744,
1744
],
1625: [
1726,
1726
],
1661: [
1704,
1703
],
1695: [
1683,
1682
],
1710: [
1675,
1674
],
1713: [
1673,
1673
],
1720: [
1669,
1669
],
1835: [
1609,
1608
],
1846: [
1603,
1602
],
1861: [
1594,
1594
],
1864: [
1593,
1592
],
1916: [
1562,
1561
],
2093: [
1462,
1462
],
2159: [
1424,
1423
],
2175: [
1414,
1413
],
2189: [
1405,
1405
],
2209: [
1394,
1393
],
2266: [
1359,
1358
],
2319: [
1327,
1326
],
2352: [
1306,
1306
],
2429: [
1260,
1260
],
2512: [
1214,
1214
],
2629: [
1141,
1141
],
2704: [
1088,
1088
],
2736: [
1064,
1063
],
2745: [
1057,
1057
],
2766: [
1042,
1042
],
2779: [
1033,
1032
],
2790: [
1025,
1024
],
2798: [
1019,
1018
],
2880: [
964,
964
],
2945: [
928,
927
],
3032: [
885,
884
],
3115: [
838,
837
],
3120: [
835,
834
],
3140: [
823,
822
],
3169: [
806,
805
],
3235: [
770,
770
],
3252: [
762,
762
],
3258: [
759,
758
],
3366: [
715,
714
],
3414: [
690,
690
],
3444: [
675,
674
],
3507: [
645,
644
],
3543: [
630,
629
],
3758: [
516,
515
],
3764: [
512,
511
],
3770: [
509,
508
],
3931: [
446,
446
],
4013: [
416,
415
],
4055: [
390,
390
],
4116: [
378,
377
],
4255: [
370,
370
],
4286: [
362,
361
],
4325: [
360,
360
],
4337: [
355,
355
],
4349: [
347,
347
],
4355: [
344,
343
],
4366: [
339,
339
],
4379: [
333,
333
],
4460: [
312,
311
],
4474: [
309,
309
],
4487: [
308,
308
],
4545: [
259,
257
],
4555: [
242,
241
]
}
If I am searching for the bucket containing 2672 how would I go about doing this? The bucket data is gathered from web scraping so I know that bucket 692 contains 2672, but I am looking for a more general solution that would allow me to only have to scrape x number of buckets before I have enough data to predict which bucket would hold any value. I will add that the first and last entries in the dict are guaranteed to hold both the largest and smallest searchable values.
Is this a known problem already? If so what is it called?
My current solution is below:
def bucket_search(buckets, n):
start_idx = None
end_idx = None
bucket_keys = list(buckets.keys())
bucket_values = list(buckets.values())
for idx, bv in enumerate(bucket_values):
high,low = bv
if n > low and n < high:
start_idx = idx
end_idx = idx
break
elif high < n:
end_idx = idx
break
if (end_idx != start_idx):
continue_search = True
tmp_start_idx = end_idx - 1
while continue_search:
high, low = bucket_values[tmp_start_idx]
if (low > n):
continue_search = False
elif (low < n and high < n):
tmp_start_idx -= 1
start_idx = tmp_start_idx
start_bucket_value = bucket_keys[start_idx]
end_bucket_value = bucket_keys[end_idx]
start_value = bucket_values[start_idx][1]
end_value = bucket_values[end_idx][0]
bucket_value_difference = end_bucket_value - start_bucket_value
value_difference = start_value - end_value
increment_amount = bucket_value_difference / value_difference
tmp_value = start_value
tmp_bucket_value = start_bucket_value
for i in range(bucket_value_difference):
tmp_value -= increment_amount
tmp_bucket_value += 1
if (n > tmp_value):
break
return tmp_bucket_value
else:
return bucket_keys[start_idx]
Currently bucket_search(data, 2672) (where data is the example data provided above) returns 704. That is close to 692 but I would think that there is a better, more accurate/precise solution.
While I used python, answers of any language are fine as long as the answer can be rewritten in another language, i.e. please don't use any niche libraries.
If there is already an answered SO question that solves this problem, I apologize as I am unsure what to call this kind of problem.

Related

Empty aggregations after filtering in elastic search v6

I have a problem that, as soon as I add a filter on one of the fields I aggregate, that the buckets are empty. The first query gets me filled buckets for my aggregations, the second below (scroll down) doesn't. I don't understand why? What is wrong?
Getting filled buckets
{
"query":{
"bool":{
"filter":[
{
"bool":{
"must":[
{
"term":{
"active":true
}
},
{
"term":{
"completed":true
}
}
]
}
}
]
}
},
"_source":[
"id",
"slug",
"profile_title",
"name",
"year",
"modified",
"last_modified_by_user",
"created",
"established",
"company.name",
"company.company",
"company.city",
"company.postal_code",
"company.translations",
"company.country.id",
"company.country.country",
"company.country.translations",
"company.country_state.id",
"company.country_state.name",
"company.country_state.translations",
"description",
"profile_images",
"profile_category_id",
"employee_number",
"primary_profile_category.name",
"primary_profile_category.translations",
"project_count",
"award_count",
"exhibition_count",
"employee_count",
"publication_count",
"competition_count",
"keywords",
"meta_description",
"domains.id",
"profile_categories",
"company.company_branches.company",
"company.company_branches.city",
"company.company_branches.id",
"company.company_branches.country_state.id",
"company.company_branches.country_state.name",
"company.company_branches.country.id",
"company.company_branches.country.country",
"company.branch_count",
"profile_specializations.name",
"profile_specializations.translations",
"publications.*",
"awards.*",
"competitions.*",
"exhibitions.*",
"translations",
"projects.project_photos"
],
"sort":[
{
"last_modified_by_user":{
"order":"desc"
}
}
],
"aggs":{
"countries":{
"nested":{
"path":"company"
},
"aggs":{
"country_ids":{
"terms":{
"field":"company.country_id"
}
},
"branch_country_ids":{
"terms":{
"field":"company.company_branches.country_id"
}
}
}
},
"country_states":{
"nested":{
"path":"company"
},
"aggs":{
"state_ids":{
"terms":{
"field":"company.state_id"
}
},
"branch_state_ids":{
"terms":{
"field":"company.company_branches.state_id"
}
}
}
}
}
}
php array result of the buckets:
[
'countries' => [
'doc_count' => (int) 3165,
'branch_country_ids' => [
'doc_count_error_upper_bound' => (int) 3,
'sum_other_doc_count' => (int) 113,
'buckets' => [
(int) 0 => [
'key' => (int) 8,
'doc_count' => (int) 143
],
(int) 1 => [
'key' => (int) 9,
'doc_count' => (int) 112
],
(int) 2 => [
'key' => (int) 11,
'doc_count' => (int) 54
],
(int) 3 => [
'key' => (int) 51,
'doc_count' => (int) 42
],
(int) 4 => [
'key' => (int) 13,
'doc_count' => (int) 22
],
(int) 5 => [
'key' => (int) 28,
'doc_count' => (int) 16
],
(int) 6 => [
'key' => (int) 42,
'doc_count' => (int) 13
],
(int) 7 => [
'key' => (int) 27,
'doc_count' => (int) 12
],
(int) 8 => [
'key' => (int) 22,
'doc_count' => (int) 10
],
(int) 9 => [
'key' => (int) 18,
'doc_count' => (int) 9
]
]
],
'country_ids' => [
'doc_count_error_upper_bound' => (int) 10,
'sum_other_doc_count' => (int) 481,
'buckets' => [
(int) 0 => [
'key' => (int) 8,
'doc_count' => (int) 940
],
(int) 1 => [
'key' => (int) 9,
'doc_count' => (int) 731
],
(int) 2 => [
'key' => (int) 11,
'doc_count' => (int) 248
],
(int) 3 => [
'key' => (int) 13,
'doc_count' => (int) 165
],
(int) 4 => [
'key' => (int) 42,
'doc_count' => (int) 138
],
(int) 5 => [
'key' => (int) 18,
'doc_count' => (int) 130
],
(int) 6 => [
'key' => (int) 10,
'doc_count' => (int) 91
],
(int) 7 => [
'key' => (int) 28,
'doc_count' => (int) 91
],
(int) 8 => [
'key' => (int) 51,
'doc_count' => (int) 84
],
(int) 9 => [
'key' => (int) 23,
'doc_count' => (int) 66
]
]
]
],
'country_states' => [
'doc_count' => (int) 3165,
'branch_state_ids' => [
'doc_count_error_upper_bound' => (int) 6,
'sum_other_doc_count' => (int) 300,
'buckets' => [
(int) 0 => [
'key' => (int) 9,
'doc_count' => (int) 50
],
(int) 1 => [
'key' => (int) 115,
'doc_count' => (int) 46
],
(int) 2 => [
'key' => (int) 118,
'doc_count' => (int) 26
],
(int) 3 => [
'key' => (int) 511,
'doc_count' => (int) 26
],
(int) 4 => [
'key' => (int) 478,
'doc_count' => (int) 20
],
(int) 5 => [
'key' => (int) 123,
'doc_count' => (int) 17
],
(int) 6 => [
'key' => (int) 870,
'doc_count' => (int) 17
],
(int) 7 => [
'key' => (int) 8,
'doc_count' => (int) 13
],
(int) 8 => [
'key' => (int) 10,
'doc_count' => (int) 13
],
(int) 9 => [
'key' => (int) 57,
'doc_count' => (int) 12
]
]
],
'state_ids' => [
'doc_count_error_upper_bound' => (int) 22,
'sum_other_doc_count' => (int) 1380,
'buckets' => [
(int) 0 => [
'key' => (int) 9,
'doc_count' => (int) 437
],
(int) 1 => [
'key' => (int) 478,
'doc_count' => (int) 157
],
(int) 2 => [
'key' => (int) 511,
'doc_count' => (int) 141
],
(int) 3 => [
'key' => (int) 118,
'doc_count' => (int) 128
],
(int) 4 => [
'key' => (int) 115,
'doc_count' => (int) 127
],
(int) 5 => [
'key' => (int) 123,
'doc_count' => (int) 125
],
(int) 6 => [
'key' => (int) 902,
'doc_count' => (int) 98
],
(int) 7 => [
'key' => (int) 52,
'doc_count' => (int) 78
],
(int) 8 => [
'key' => (int) 138,
'doc_count' => (int) 77
],
(int) 9 => [
'key' => (int) 8,
'doc_count' => (int) 74
]
]
]
]
]
Empty buckets after filtering by country id
{
"query":{
"bool":{
"filter":[
{
"bool":{
"must":[
{
"bool":{
"must":[
{
"term":{
"company.country_id":9
}
},
{
"term":{
"company.company_branches.country_id":9
}
}
]
}
},
{
"term":{
"active":true
}
},
{
"term":{
"completed":true
}
}
]
}
}
]
}
},
"_source":[
"id",
"slug",
"profile_title",
"name",
"year",
"modified",
"last_modified_by_user",
"created",
"established",
"company.name",
"company.company",
"company.city",
"company.postal_code",
"company.translations",
"company.country.id",
"company.country.country",
"company.country.translations",
"company.country_state.id",
"company.country_state.name",
"company.country_state.translations",
"description",
"profile_images",
"profile_category_id",
"employee_number",
"primary_profile_category.name",
"primary_profile_category.translations",
"project_count",
"award_count",
"exhibition_count",
"employee_count",
"publication_count",
"competition_count",
"keywords",
"meta_description",
"domains.id",
"profile_categories",
"company.company_branches.company",
"company.company_branches.city",
"company.company_branches.id",
"company.company_branches.country_state.id",
"company.company_branches.country_state.name",
"company.company_branches.country.id",
"company.company_branches.country.country",
"company.branch_count",
"profile_specializations.name",
"profile_specializations.translations",
"publications.*",
"awards.*",
"competitions.*",
"exhibitions.*",
"translations",
"projects.project_photos"
],
"sort":[
{
"last_modified_by_user":{
"order":"desc"
}
}
],
"aggs":{
"countries":{
"nested":{
"path":"company"
},
"aggs":{
"country_ids":{
"terms":{
"field":"company.country_id"
}
},
"branch_country_ids":{
"terms":{
"field":"company.company_branches.country_id"
}
}
}
},
"country_states":{
"nested":{
"path":"company"
},
"aggs":{
"state_ids":{
"terms":{
"field":"company.state_id"
}
},
"branch_state_ids":{
"terms":{
"field":"company.company_branches.state_id"
}
}
}
}
}
}
Aggreations as php array result:
[
'countries' => [
'doc_count' => (int) 0,
'branch_country_ids' => [
'doc_count_error_upper_bound' => (int) 0,
'sum_other_doc_count' => (int) 0,
'buckets' => []
],
'country_ids' => [
'doc_count_error_upper_bound' => (int) 0,
'sum_other_doc_count' => (int) 0,
'buckets' => []
]
],
'country_states' => [
'doc_count' => (int) 0,
'branch_state_ids' => [
'doc_count_error_upper_bound' => (int) 0,
'sum_other_doc_count' => (int) 0,
'buckets' => []
],
'state_ids' => [
'doc_count_error_upper_bound' => (int) 0,
'sum_other_doc_count' => (int) 0,
'buckets' => []
]
]
]
According to your aggregation, company is a nested field, so your filtering criteria must also leverage the nested query:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"nested": { <-- use nested here
"path": "company",
"query": {
"bool": {
"must": [
{
"term": {
"company.country_id": 9
}
},
{
"term": {
"company.company_branches.country_id": 9
}
}
]
}
}
}
},
{
"term": {
"active": true
}
},
{
"term": {
"completed": true
}
}
]
}
}
]
}
},
"aggs": {
...

Elasticsearch query for simple category search, sorting by price and getting records by range

I want to write query with following condition :
search by category (like category = 'cat1')
and with price range (and price between 100 to 500)
and sort by price (low to high)
I tried:
$params = [
'index' => 'my_index',
'type' => 'product',
'body' => [
//"from" => 0, "size" => 2,
"sort" => [
["default_product_low_price.sale_price" => ["order" => "asc"]]
],
'query'=> $query,
"aggs" => [
"default_product_low_price" => [
"nested" => [
"path" => "default_product_low_price"
],
"aggs" => [
"range" => ["default_product_low_price.sale_price" => [ "gte" => '790',
"lte" => '1000' ]],
//"max_price" => ["max" => [ "field" => "default_product_low_price.sale_price" ]]
],
]
]
]
];
But I am getting an error
Bad Request 400 Exception in GuzzleConnection.php line 277: error.
Please guide me where I am wrong? What is the right query?
I think this should be your query :
$params = [
'index' => 'my_index',
'type' => 'product',
'body' => [
"sort" =>[
["default_product_low_price.sale_price" => ["order" => "asc"]]
],
"query"=> [
"filtered"=> [
"query"=> [
"match_all"=> []
],
"query"=>[
"term"=> [
"category.name"=> "jeans"
]
],
"filter"=> [
"nested"=> [
"path"=> "default_product_low_price",
"filter"=> [
"bool"=> [
"must"=> [
[
"range"=> [
"default_product_low_price.sale_price"=> [
"gte"=> 100,
"lte"=> 200,
]
]
]
]
]
]
]
]
]
]
]
];

CKeditor - How to bind a keystroke to apply <code> tag to selected text

I have bound almost all the keystrokes I need for CKEditor, save for <code>. How can bind a keystroke for that HTML tag?
config.keystrokes = [
[ CKEDITOR.CTRL + 32 /*space*/, 'removeFormat' ],
[ CKEDITOR.CTRL + 56 /*8*/, 'bulletedlist' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 56 /*8*/, 'bulletedListStyle' ],
[ CKEDITOR.CTRL + 77 /*M*/, 'indent' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 77 /*M*/, 'outdent' ],
[ CKEDITOR.CTRL + 188 /*COMMA*/, 'subscript' ],
[ CKEDITOR.CTRL + 190 /*PERIOD*/, 'superscript' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 73 /*I*/, 'image' ],
[ CKEDITOR.CTRL + 75 /*K*/, 'link' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 75 /*K*/, 'unlink' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 70 /*F*/, 'find' ],
[ CKEDITOR.ALT + 88 /*X*/, 'maximize' ],
[ CKEDITOR.CTRL + 113 /*F2*/, 'preview' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 80 /*P*/, 'print' ],
[ CKEDITOR.CTRL + 72 /*H*/, 'replace' ],
[ CKEDITOR.ALT + 83 /*S*/, 'scaytcheck' ],
[ CKEDITOR.ALT + 66 /*B*/, 'showblocks' ],
// [ CKEDITOR.ALT + 90 /*Z*/, 'source' ],
[ CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ],
[ CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ],
[ CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ],
[ CKEDITOR.CTRL + 90 /*Z*/, 'undo' ],
[ CKEDITOR.CTRL + 89 /*Y*/, 'redo' ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'redo' ],
[ CKEDITOR.CTRL + 76 /*L*/, 'link' ],
[ CKEDITOR.CTRL + 66 /*B*/, 'bold' ],
//[ CKEDITOR.CTRL + CKEDITOR.SHIFT + CKEDITOR.ALT + 68 /*D*/, 'code' ],
[ CKEDITOR.CTRL + 73 /*I*/, 'italic' ],
[ CKEDITOR.CTRL + 85 /*U*/, 'underline' ],
[ CKEDITOR.ALT + 109 /*-*/, 'toolbarCollapse' ]
];
This is something that you cannot have just by editing the config. Go ahead with the following code (+fiddle):
var codeStyle = new CKEDITOR.style( {
element: 'code'
} );
CKEDITOR.replace( 'editor', {
on: {
instanceReady: function() {
// Register a new command that applies the style.
this.addCommand( 'codeCommand', new CKEDITOR.styleCommand( codeStyle ) );
// Bind the command to CTRL+SHIFT+L.
this.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 76, 'codeCommand' );
}
}
} );
Also see docs for: editor.addCommand, editor.setKeystroke and CKEDITOR.styleCommand.

How find all overlapping circles from radius of central circle?

How to do an intersection or overlap query in mongo shell - what circles overlap my search region? Within relate only to the center position but doesn't include radius of the other circles in searched scope.
Mongo:
# My bad conception:
var search = [[30, 30], 10]
db.places.find({circle : {"$within" : {"$center" : [search]}}})
Now I can obtain only this circles within central point lies in searched area of circle:
Ruby:
# field :circle, type: Circle # eg. [ [ 30, 30 ], 10 ]
field :radius, type: Integer
field :location, :type => Array, :spatial => true
spatial_index :location
Places.within_circle(location: [ [ 30, 30 ], 10 ])
# {"$query"=>{"location"=>{"$within"=>{"$center"=>[[30, 30], 10]}}}
I created example data with additional location (special index) and radius instead circle because circle isn't supported by mongodb geo index:
{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 }
{ "_id" : 2, "name" : "b", "circle" : [ [ 10, 10 ], 5 ], "latlng" : [ 10, 10 ], "radius" : 5 }
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 }
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30}
{ "_id" : 6, "name" : "f", "circle" : [ [ 80, 80 ], 20 ], "latlng" : [ 80, 80 ], "radius" : 20}
Desired query result:
{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 }
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 }
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30}
Solution below assumes that I get all rows and then filter on the ruby side my radius but it returns only:
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}
I'm not familiar with mongodb but I assume that in [[x, y], r] values mean
x: value of the center on the axis x.
y: value of the center on the axis y.
r: circle radius.
Say you have circle S which is your search and a random circle A. Then you could calcule the distance between both circles' center (S.center and A.center) and see if it is inferior to those both circles radius added (S.r + A.r).
def distance_between(a, b)
((b.first - a.first)**2 + (b.last - a.last)**2)**0.5
end
elements = [{ _id: 1, name: "a", circle: [ [ 5, 5 ], 40 ] },
{ _id: 2, name: "b", circle: [ [ 10, 10 ], 5 ] },
{ _id: 3, name: "c", circle: [ [ 20, 20 ], 5 ] },
{ _id: 4, name: "d", circle: [ [ 30, 30 ], 50 ] },
{ _id: 5, name: "e", circle: [ [ 80, 80 ], 30 ] },
{ _id: 6, name: "f", circle: [ [ 80, 80 ], 20 ] }]
search = [[30, 30], 10]
elements.select do |elem| circle = elem[:circle]
distance_between(circle.first, search.first) <= circle.last + search.last
end
#{:_id=>1, :name=>"a", :circle=>[[5, 5], 40]}
#{:_id=>3, :name=>"c", :circle=>[[20, 20], 5]}
#{:_id=>4, :name=>"d", :circle=>[[30, 30], 50]}
Unfortunately there is currently no capability in mongo to directly query about overlapping objects, only points within objects.
#oldergod's answer describes the algorithm to calculate whether two circles overlap.
Here is a work-around in the shell based on that calculation:
function distance(a, b) {
return Math.pow(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2), 0.5);
}
On your sample data inserted into collection 'circle':
> db.circle.find().forEach(
function(c) {
if ( (distance(c.latlng, search.latlng) < c.radius + search.radius) )
{
print(c.name);
}
} )
a
c
d
>

How do you do an inner product with ruby NArray?

I'm looking for something like the inner method in numpy.
I have a 4 dimensional array called 'labels' and a one dimensional array (a vector) called 'discounts'. In numpy I can do numpy.inner(labels, discounts) and this will do the inner product between discounts and each row of the last dimension of labels returning a 3 dimensional array. I can not figure out how to do the same thing with NArray in ruby.
$ irb -rnarray
irb(main):001:0> a=NArray.float(3,2,2).indgen
=> NArray.float(3,2,2):
[ [ [ 0.0, 1.0, 2.0 ],
[ 3.0, 4.0, 5.0 ] ],
[ [ 6.0, 7.0, 8.0 ],
[ 9.0, 10.0, 11.0 ] ] ]
irb(main):002:0> b=NArray[1..3]
=> NArray.int(3):
[ 1, 2, 3 ]
irb(main):003:0> a*b
=> NArray.float(3,2,2):
[ [ [ 0.0, 2.0, 6.0 ],
[ 3.0, 8.0, 15.0 ] ],
[ [ 6.0, 14.0, 24.0 ],
[ 9.0, 20.0, 33.0 ] ] ]
irb(main):004:0> (a*b).sum(0)
=> NArray.float(2,2):
[ [ 8.0, 26.0 ],
[ 44.0, 62.0 ] ]
irb(main):005:0> a.mul_add(b,0)
=> NArray.float(2,2):
[ [ 8.0, 26.0 ],
[ 44.0, 62.0 ] ]

Resources