Pad an array with 0's swift [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am attempting to pad an an array with zeros but cannot find a succinct way to do this in swift.
If I have array x = [1,2,3 ; 4,5,6 ; 7,8,9]
in matlab I could use the command
y = [zeros(1,3+2);zeros(3,1),x,zeros(3,1);zeros(1,3+2)]
giving the desired output array of [0,0,0,0,0; 0,1,2,3,0 ; 0,4,5,6,0 ; 0,7,8,9,0 ; 0,0,0,0,0]
However so far in a swift playground I have only been able to refer to each element individually to correctly form the new array.
The methods I have tried so far using x as the input and y as the output, the first similar to matlab,
var x = [[1,2,3,],[4,5,6],[7,8,9]]
var y = [[0,0,0,0,0],[0,x[0],0],[0,x[1],0],[0,x[2],0],[0,0,0,0,0]]
The second being a loop
for i in 0 ..< x.count + 1 {
if i == 0 || i == x.count - 1 {
y[i] = [0,0,0,0,0]
}
else{
y[i] = [0, x[i-1] ,0]
}
}
Rather than looking like a standard array in the Xcode playground preview this is the output given.
[[0, 0, 0, 0, 0], [0, […], 0], [0, 0, 0, 0, 0], [0, […], 0], [0, 0, 0, 0, 0]]
which also prints to the console very strangely, using the code
for i in 0 ..< y.count {
print("\(y[i])")
}
the output is
(
0,
0,
0,
0,
0
)
(
0,
(
1,
2,
3
),
0
)
(
0,
0,
0,
0,
0
)
(
0,
(
7,
8,
9
),
0
)
(
0,
0,
0,
0,
0
)
as opposed to the expected
[0, 0, 0, 0, 0]
[0, 1, 2, 3, 0]
[0, 4, 5, 6, 0]
[0, 7, 8, 9, 0]
[0, 0, 0, 0, 0]
What is the best way to do this?

I made a generic version of appzYourLife's answer that can take any arbitrary nested array type. It also adds support for top and bottom padding
extension Array where Element: _ArrayType {
typealias InnerElement = Element.Generator.Element
func pad2DArray(with padding: InnerElement,
top: Int = 0, left: Int = 0,
right: Int = 0, bottom: Int = 0) -> [[InnerElement]] {
let newHeight = self.count + top + bottom
let newWidth = (self.first?.count ?? 0) + left + right
var paddedArray = [[InnerElement]](count: newHeight, repeatedValue:
[InnerElement](count: newWidth, repeatedValue: padding))
for (rowIndex, row) in self.enumerate() {
for (columnIndex, element) in row.enumerate() {
paddedArray[rowIndex + top][columnIndex + left] = element
}
}
return paddedArray
}
}
var input = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
let result = input.pad2DArray(with: 0, top: 1, left: 1, right: 1, bottom: 1)
/*
result:
[
[0, 0, 0, 0, 0],
[0, 1, 2, 3, 0],
[0, 4, 5, 6, 0],
[0, 7, 8, 9, 0],
[0, 0, 0, 0, 0],
]
*/

Extension
If you define this extension
extension _ArrayType where Element == Int {
func pad(left left: Int, right: Int) -> [Int] {
let leftSide = [Int](count: left, repeatedValue: 0)
let rightSide = [Int](count: right, repeatedValue: 0)
return leftSide + (self as! [Int]) + rightSide
}
}
you can then write
[1,2,3].pad(left: 1, right: 1) // [0, 1, 2, 3, 0]

Definitely not as elegant as the accepted answer, but it works nonetheless:
var x = [[1,2,3,],[4,5,6],[7,8,9]]
var y = [[Int]]()
y.insert([0,0,0,0,0], atIndex: 0)
for i in 0 ..< x.count {
var intArray: [Int] = []
for number in x[i] {
intArray.append(number)
}
intArray.insert(0, atIndex: 0)
intArray.insert(0, atIndex: intArray.count)
y.append(intArray)
}
y.insert([0,0,0,0,0], atIndex: x.count + 1)
The output from
for i in 0 ..< y.count {
print("\(y[i])")
}
is
[0, 0, 0, 0, 0]
[0, 1, 2, 3, 0]
[0, 4, 5, 6, 0]
[0, 7, 8, 9, 0]
[0, 0, 0, 0, 0]

Related

Given a 2D array, find out if a given node is surrounded

Given a 2D array where each digit represents a different color, I want to be able to find out if a given node in the array is surrounded completely by one color. For example, in the 2d array below, I want to be able to confirm that the node at [3][3] is completely surrounded by the color represented by "1". Is there an existing common algorithm that accomplishes this?
{{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 2, 2, 2, 2, 1, 1, 0},
{1, 1, 1, 2, 2, 1, 1, 1},
{1, 1, 1, 2, 2, 2, 2, 1},
{1, 1, 1, 1, 1, 2, 1, 1},
{1, 1, 1, 1, 1, 1, 2, 1}}
EDIT: Sorry I am not asking about whether the target node is immediately surrounded. I am asking about whether if you move out from the target node, you can reach the edge of the array without crossing over the boundary color.
My current code is the following, but it's not quite working
let squaresChecked = []
let squareSurrounded = true
let boardSize = 15
let gameBoard = new Array(boardSize)
for(let i=0; i<gameBoard.length; i++){
gameBoard[i] = Array(boardSize).fill('white')
}
checkSurrounded(x, y, boundaryColor){
if(x >= boardSize || y >= boardSize || x < 0 || y < 0){
squareSurrounded = false
return
}
if(gameBoard[x][y] === boundaryColor){return}
if(squaresChecked.includes(x + ' ' + y)){return}
squaresChecked.push(x + ' ' + y)
checkSurrounded(x+1, y, boundaryColor)
checkSurrounded(x-1, y, boundaryColor)
checkSurrounded(x, y+1, boundaryColor)
checkSurrounded(x, y-1, boundaryColor)
}
This should check for top, left, right, bottom for given cell at row,col in 2D array if surrounded by var surroundedBy (1).
row = 2
col = 2
arr = [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 1, 1, 0],
[1, 1, 1, 2, 2, 1, 1, 1],
[1, 1, 1, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 2, 1, 1],
[1, 1, 1, 1, 1, 1, 2, 1]]
surroundedBy = 1
if(arr[row-1][col] ===surroundedBy && arr[row+1][col] === surroundedBy && arr[row][col - 1] === surroundedBy && arr[row][col + 1] === surroundedBy) {
console.log('surrounded');
}else{
console.log('not surrounded');
}

Tensorflow.js cropping image return zeros tensor

I have a custom model which takes in cropped faces from BlazeFace Model then outputs a prediction of 3 classes.
Before sending them to my custom model I resize the cropped faces to be of shape [1,224,224,3]
Output at every prediction:
Float32Array [
6.522771905936864e-11,
3.698188456857654e-12,
1,
]
Code for resizing the cropped faces and making predictions:
const getPrediction = async tensor => {
if (!tensor) {
console.log("Tensor not found!");
}
// Load both models
const bfModel = await blazeFaceModel;
const returnTensors = true;
const faces = await bfModel
.estimateFaces(tensor, returnTensors)
.catch(e => console.log(e));
// Reshape tensor from rank 3 to rank 4
const tensorReshaped = tensor.reshape([1, 224, 224, 3]);
const scale = {
height: styles.camera.height / tensorDims.height,
width: styles.camera.width / tensorDims.width
};
// Faces is an array of objects
if (!isEmpty(faces)) {
// Setting faces in state
setModelFaces({ faces });
}
//Looping over array of objects in faces
faces.map((face, i) => {
const { topLeft, bottomRight } = face;
const width = Math.floor(
bottomRight.dataSync()[0] - topLeft.dataSync()[0] * scale.width
);
const height = Math.floor(
bottomRight.dataSync()[1] - topLeft.dataSync()[1] * scale.height
);
const boxes = tf
.concat([topLeft.dataSync(), bottomRight.dataSync()])
.reshape([-1, 4]);
// Cropping out faces from original tensor
const crop = tf.image.cropAndResize(
tensorReshaped,
boxes,
[0],
[height, width]
);
// Resize cropped faces to [1,224,224,3]
const alignCorners = true;
const imageResize = tf.image.resizeBilinear(
crop,
[224, 224],
alignCorners
);
makePrediction(imageResize);
});
};
// Make predictions on the tensors
const makePrediction = async image => {
if (!image) {
console.log("No input!");
}
const model = await loadedModel;
const prediction = await model.predict(image, { batchSize: 1 });
if (!prediction || isEmpty(prediction)) {
console.log("Prediction not available");
}
console.log(prediction);
console.log(prediction.dataSync());
};
EDIT
I tried changing the batch size when making predictions to 1 and still the same issue
I tried reconverting the keras model to tfjs format and still the same issue
I tried disposing of the tensor after making a prediction but still there is an error
So i printed out the tensors of the resized faces and its a lot of 0's
Tensor before prediction
Tensor
[[[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
...
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]]]
undefined
Tensor during prediction
Tensor
[[[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
...
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]]]
undefined
boxes of tf.image.cropAndResize are normalized coordinates between 0 and 1. Therefore topLeft and bottomRight should be normalized by using [imageWidth, imageHeight]
normalizedTopLeft = topLeft.div(tensor.shape.slice(-3, -2))
// slice will get [h, w] of a tensor of shape [b, h, w, ch] or [h, w, ch]
// do likewise for bottomRight
// use normalizedTopLeft instead of topLeft for cropping

How to change a value of an array which is indexed several times?

Let's have A like below :
A = np.array([[0, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 1, 0, 0],
[0, 0, 0, 0, 0]])
And now, I have to take all the lines which have a 1 on first column :
A[A[:, 0] > 0]
return: array([[1, 0, 0, 0, 0],
[1, 0, 1, 0, 0]])
And now, I want to modify the first column of the second line ? How can I do it ? Because this is not working :
A[A[:, 0] > 0][1, 1] = 1
A
array([[0, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 3, 0, 0, 0],
[1, 0, 1, 0, 0],
[0, 0, 0, 0, 0]])
My code is more complicated than this one, and so, the condition have to be done in two times like here : (1) > 0 and (2) [1, 1].

How to initialise a three dimensional ruby array

I want to initialise a three dimensional ruby array. For a two-dimensional array, I can do
a = Array.new(4){ Array.new(5, 0) }
so I have tried
a = Array.new(4) { Array.new(5, Array.new(6, 0)) }
but if I do a[1][2][3] = 5, it not only sets that element to 5, it sets the corresponding element to 5 in other sub arrays i.e.
[[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0]],
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]]
The issue is that if you pass the value as an argument, you will get an array where each value refers to that same object. You do exactly that with:
Array.new(5, Array.new(6, 0))
You can use Array#*, i.e array multiplication instead:
[[[0] * 6] * 5] * 4
Just use the same syntax (with a block instead of an argument : Array.new(n){...}) for all the dimensions.
a = Array.new(4) { Array.new(5) { Array.new(6, 0) } }
This way, your code will create 20 distincts Array.new(6, 0) sub-sub-arrays instead of replicating the same object 5 times.
require 'pp'
a = Array.new(4) { Array.new(5) { Array.new(6, 0) } }
a[1][2][3] = 5
pp a
# [[[0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0]],
# [[0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 5, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0]],
# [[0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0]],
# [[0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0]]]
The following worked properly.
a=Array.new(4){ Array.new(5) { Array.new(6,0) }}
You can use recursion to initialize the elements of a multidimensional array of any dimension.1
Code
def init(n, *rest)
rest.empty? ? Array.new(n, 0) : Array.new(n) { init(*rest) }
end
Examples
dims = [2, 3, 2]
a = init(*dims)
#=> [[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
a[0][0][0] = 1
a #=> [[[1, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
dims = [2, 3, 2, 4, 2, 3]
a = init(*dims)
a.flatten.size
#=> 288 (= 2*3*2*4*2*3)
a[0][0][0][0][0][0] = 1
a.flatten.count(1)
#=> 1
Explanation
The steps are as follows.
Suppose, as in the example,
dims = [2, 3, 2]
Then
n, *rest = dims
#=> [2, 3, 2]
n #=> 2
rest
#=> [3, 2]
As rest.empty? #=> false, the method returns
Array.new(2) { init(*[3, 2]) } # (1)
#=> [[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
To obtain this result, we execute the block
{ init(*[3, 2]) }
for each of the two elements of the array being constructed. This requires us to compute init([3, 2]) (same as { init(3, 2) }), which is done as follows.
n, *rest = [3, 2]
#=> [3, 2]
n #=> 3
rest
#=> [2]
Again, as rest.empty? #=> false, we return
Array.new(3) { init(*[2]) } # (2)
#=> [[0, 0], [0, 0], [0, 0]]
to expression (1) above. For each of the 3 elements of this array we execute the block
{ init(*[2]) }
This requires us to compute init([2]), which is done as follows.
n, *rest = [2]
#=> [2]
n #=> 2
rest
#=> []
This time, since rest.empty? #=> true, we compute and return
Array.new(2, 0)
#=> [0, 0]
to expression (2) above.
1 Yes, there's no such thing as a "multidimensional array" in Ruby, but I expect readers to know what I mean. The alternative is something like "...of an array containing nested arrays of equal size with any number of levels of nesting", but even that is incomplete as it fails to exclude, for example, [[1, [2,3]], [4,5]]. It would be helpful if Ruby had a name for such objects.

which tasks can simple perceptron perform?

I'm trying to teach simple single neuron perceptron to recognize repetitive sequences of 1.
here is data I use to teach it:
learning_signals = [
[[1, 1, 0, 0], 1],
[[1, 1, 0, 1], 1],
[[1, 1, 1, 0], 1],
[[0, 1, 1, 0], 1],
[[0, 1, 1, 1], 1],
[[0, 0, 1, 1], 1],
[[1, 0, 1, 1], 1],
[[0, 0, 0, 0], 0],
[[1, 0, 0, 0], 0],
[[0, 1, 0, 0], 0],
[[0, 0, 1, 0], 0],
[[0, 0, 0, 1], 0],
[[1, 0, 1, 0], 0],
[[1, 0, 0, 1], 0],
# [[0, 1, 0, 1], 0],
This is the array of learning templates each of them are array of data and correct result for that data.
As you see. last row commented - if I do uncomment it - perceptron will fail to learn. without it perceptron does not work right in case with "0101". So the question is:
Is this task can be solved with single neuron perceptron or should I use few layered perceptron?
How can I determine which tasks can be solved with such a simple perceptron? Are there any rule that I can apply to my task and say that it could be done with simple perceptron?
here is the code of perceprton written in coffeescript:
class window.Perceptron
weights: []
calc: (signal) ->
#neuron.calc signal
adjust: ->
foo: 0.1
calc: (signal) ->
sum = 0
for s, i in signal
sum += s*#weights[i]
if sum>0.5 then return 1 else return 0
sum
learn: (templates) ->
#weights = []
for i in [1..templates[0][0].length]
#weights.push Math.random()
li = 0
max_li = 50000
console.log #weights
while true
gerror = 0
li++
for template, i in templates
res = #calc template[0]
# console.log "result: #{res}"
error = template[1] - res
gerror += Math.abs error
for weight, i in #weights
#weights[i] += #foo*error*template[0][i]
if ((gerror == 0) || li > max_li) then break
if gerror == 0
console.log "Learned in #{li} iterations"
else
console.log "Learning failed after #{max_li} iterations"
console.log #weights

Resources