This repository has been archived by the owner on Sep 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
resize.hhs
136 lines (119 loc) · 4.46 KB
/
resize.hhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* @author Jianan Lin (林家南)
* @param input - an array / matrix / tensor
* @param sizes - an array such as [2, 3, 2] or [2, -1]
* @param defaultValue - a number filling the remained space
* @returns - an 1-d array, 2-d matrix or more-d tensor with specified size
* Notice if sizes = [..., -1], then defaultValue will be never used
*
*/
function resize(input, sizes = [-1], defaultValue = 0) {
*import math: flatten
*import math: ndim
*import math: deep_copy
// wrong argument number
if (arguments.length === 0) {
throw new Error('Exception occurred in resize - no argument given');
}
else if (arguments.length > 3) {
throw new Error('Exception occurred in resize - wrong argument number');
}
// type check
if (!(Array.isArray(input)) && !(input instanceof Mat) && !(input instanceof Tensor)) {
throw new Error('Exception occurred in resize - argument[0] is not a Mat, Tensor or JS Array');
}
if (!(Array.isArray(sizes)) && !(sizes instanceof Mat) && !(sizes instanceof Tensor)) {
throw new Error('Exception occurred in resize - argument[1] is not a Mat, Tensor or JS Array');
}
// dimension check
if (ndim(sizes) !== 1) {
throw new Error('Exception occurred in resize - argument[1] is not 1-dimensional');
}
// size check
let dimension = sizes.length;
// the last element can be -1, others must be positive integers
for (let i = 0; i < dimension - 1; i++) {
if (sizes[i] <= 0 || parseInt(sizes[i]) !== sizes[i]) {
throw new Error('Exception occurred in resize - elements in sizes must be positive integers');
}
}
if ((sizes[dimension - 1] <= 0 && sizes[dimension - 1] !== -1) || (parseInt(sizes[dimension - 1]) !== sizes[dimension - 1])) {
throw new Error('Exception occurred in resize - the last element in sizes must be positive integer or -1');
}
// process the input
let in_type = (input instanceof Mat) || (input instanceof Tensor);
let raw_in = (in_type) ? input.clone().val : deep_copy(input);
raw_in = flatten(raw_in);
let length = raw_in.length;
// determine whether we can resize
let product = 1;
for (let i = 0; i < dimension - 1; i++) {
product = product * sizes[i];
}
// if (length % product !== 0) {
// throw new Error('Exception occurred in resize - the product of array sizes must be a divisor');
// }
// if (sizes[dimension - 1] === -1 && product * sizes[dimension - 1] !== length) {
// throw new Error('Exception occurred in resize - the product of array sizes must be a divisor');
// }
if (sizes[dimension - 1] === -1) {
if (length % product !== 0) {
throw new Error('Exception occurred in resize - the product of array sizes must be a divisor');
}
else {
sizes[dimension - 1] = length / product;
}
}
else {
product = product * sizes[dimension - 1];
if (product > length) {
for (let i = 0; i < product - length; i++) {
raw_in.push(defaultValue);
}
}
else if (product < length) {
for (let i = 0; i < length - product; i++) {
raw_in.pop();
}
}
length = product;
}
// next we resize the array
if (dimension === 1) {
return raw_in;
}
else {
let result = [];
for (let i = 0; i < sizes[0]; i++) {
let temp = resize_helper(raw_in, length / sizes[0] * i, length / sizes[0] * (i + 1), sizes, 1);
result.push(temp);
}
if (ndim(result) == 2) {
return mat(result);
}
else {
return new Tensor(result);
}
}
// use this recursive function
function resize_helper(input, start, end, sizes, index) {
// the end case
if (index === sizes.length - 1) {
let result = [];
for (let i = 0; i < end - start; i++) {
result.push(input[i + start]);
}
return result
}
// the recursion
else {
let result = [];
let distance = end - start;
for (let i = 0; i < sizes[index]; i++) {
let temp = resize_helper(input, start + distance / sizes[index] * i, start + distance / sizes[index] * (i + 1), sizes, index + 1);
result.push(temp)
}
return result;
}
}
}