<jupyter_start><jupyter_text>Math Part 2<jupyter_code>from __future__ import print_function
import tensorflow as tf
import numpy as np
from datetime import date
date.today()
author = "kyubyong. https://github.com/Kyubyong/tensorflow-exercises"
tf.__version__
np.__version__
sess = tf.InteractiveSession()<jupyter_output><empty_output><jupyter_text>NOTE on notation* _x, _y, _z, ...: NumPy 0-d or 1-d arrays* _X, _Y, _Z, ...: NumPy 2-d or higer dimensional arrays* x, y, z, ...: 0-d or 1-d tensors* X, Y, Z, ...: 2-d or higher dimensional tensors  Matrix Math Functions Q1. Create a diagonal tensor with the diagonal values of x.<jupyter_code>_x = np.array([1, 2, 3, 4])
x = tf.convert_to_tensor(_x)

out = tf.diag(x)
print(out.eval())

_out = np.diag(_x)
assert np.array_equal(out.eval(), _out)<jupyter_output>[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]<jupyter_text>Q2. Extract the diagonal of X.<jupyter_code>_X = np.array(
[[1, 0, 0, 0],
 [0, 2, 0, 0],
 [0, 0, 3, 0],
 [0, 0, 0, 4]])
X = tf.convert_to_tensor(_X)

out = tf.diag_part(X)
print(out.eval())

_out = np.diag(_X)
assert np.array_equal(out.eval(), _out)
# Did you notice that np.diag() works like tf.diag or tf.diag_part 
# according to the rank/dimensions of the input array?<jupyter_output>[1 2 3 4]<jupyter_text>Q3. Permutate the dimensions of x such that the new tensor has shape (3, 4, 2).<jupyter_code>_X = np.random.rand(2,3,4)
X = tf.convert_to_tensor(_X)

out = tf.transpose(X, [1, 2, 0])
print(out.get_shape())

_out = np.transpose(_X, [1, 2, 0])
assert np.array_equal(out.eval(), _out) # tf.transpose == np.transpose<jupyter_output>(3, 4, 2)<jupyter_text>Q4. Construct a 3 by 3 identity matrix.<jupyter_code>out = tf.eye(3)
print(out.eval())

assert np.array_equal(out.eval(), np.eye(3)) # tf.eye == np.eye<jupyter_output>[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]<jupyter_text>Q5. Predict the result of this.<jupyter_code>_X = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
X = tf.convert_to_tensor(_X)

diagonal_tensor = tf.matrix_diag(X)
diagonal_part = tf.matrix_diag_part(diagonal_tensor)

print("diagonal_tensor =\n", diagonal_tensor.eval())
print("diagonal_part =\n", diagonal_part.eval())<jupyter_output>diagonal_tensor =
 [[[1 0 0 0]
  [0 2 0 0]
  [0 0 3 0]
  [0 0 0 4]]

 [[5 0 0 0]
  [0 6 0 0]
  [0 0 7 0]
  [0 0 0 8]]]
diagonal_part =
 [[1 2 3 4]
 [5 6 7 8]]<jupyter_text>Q6. Transpose the last two dimensions of x.<jupyter_code>_X= np.random.rand(1, 2, 3, 4)
X = tf.convert_to_tensor(_X)

out1 = tf.matrix_transpose(X)
out2 = tf.transpose(X, [0, 1, 3, 2])
print(out1.eval().shape)
assert np.array_equal(out1.eval(), out2.eval())<jupyter_output>(1, 2, 4, 3)<jupyter_text>Q7. Multiply X by Y.<jupyter_code>_X = np.array([[1, 2, 3], [4, 5, 6]])
_Y = np.array([[1, 1], [2, 2], [3, 3]])
X = tf.convert_to_tensor(_X)
Y = tf.convert_to_tensor(_Y)

out = tf.matmul(X, Y)
print(out.eval())

_out = np.dot(_X, _Y)
assert np.array_equal(out.eval(), _out) # tf.matmul(2d, 2d) == np.dot(2d, 2d)<jupyter_output>[[14 14]
 [32 32]]<jupyter_text>Q8. Multiply X and Y. The first axis represents batches.<jupyter_code>_X = np.arange(1, 13, dtype=np.int32).reshape((2, 2, 3))
_Y = np.arange(13, 25, dtype=np.int32).reshape((2, 3, 2))
X = tf.convert_to_tensor(_X)
Y = tf.convert_to_tensor(_Y)
out = tf.matmul(X, Y)
print(out.eval())

# Note that this is not the same as the following.
#_out = np.dot(_X, _Y)
#print(_out)
# in TF 1.0, batch_matmul was absorbed in matmul.<jupyter_output>[[[ 94 100]
  [229 244]]

 [[508 532]
  [697 730]]]<jupyter_text>Q9. Compute the determinant of X.<jupyter_code>_X = np.arange(1, 5, dtype=np.float32).reshape((2, 2))
X = tf.convert_to_tensor(_X)

out = tf.matrix_determinant(X)
print(out.eval())<jupyter_output>-2.0<jupyter_text>Q10. Compute the inverse of X.<jupyter_code>_X = np.arange(1, 5, dtype=np.float64).reshape((2, 2))
X = tf.convert_to_tensor(_X)

out = tf.matrix_inverse(X)
print(out.eval())

_out = np.linalg.inv(_X)
assert np.allclose(out.eval(), _out)<jupyter_output>[[-2.   1. ]
 [ 1.5 -0.5]]<jupyter_text>Q11. Get the lower-trianglular in the Cholesky decomposition of X.<jupyter_code>_X = np.array([[4, 12, -16], [12, 37, -43], [-16, -43, 98]], np.float32)
X = tf.convert_to_tensor(_X)

out = tf.cholesky(X)
print(out.eval())

_out = np.linalg.cholesky(_X)
assert np.array_equal(out.eval(), _out)<jupyter_output>[[ 2.  0.  0.]
 [ 6.  1.  0.]
 [-8.  5.  3.]]<jupyter_text>Q12. Compute the eigenvalues and eigenvectors of X.<jupyter_code>_X = np.diag((1, 2, 3))
X = tf.convert_to_tensor(_X, tf.float32)

eigenvals, eigenvecs = tf.self_adjoint_eig(X)
print("eigentvalues =\n", eigenvals.eval())
print("eigenvectors =\n", eigenvecs.eval())

_eigenvals, _eigenvecs = np.linalg.eig(_X)
assert np.allclose(eigenvals.eval(), _eigenvals)
assert np.allclose(eigenvecs.eval(), _eigenvecs)<jupyter_output>eigentvalues =
 [ 1.  2.  3.]
eigenvectors =
 [[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]<jupyter_text>Q13. Compute the singular values of X.<jupyter_code>_X = np.array(
[[1, 0, 0, 0, 2], 
 [0, 0, 3, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 2, 0, 0, 0]], dtype=np.float32)
X = tf.convert_to_tensor(_X)

out = tf.svd(X, compute_uv=False)
print(out.eval())

_out = np.linalg.svd(_X, compute_uv=False)
assert np.allclose(out.eval(), _out)<jupyter_output>[ 3.          2.23606801  2.          0.        ]<jupyter_text>Reduction Q14. Predict the results of these.<jupyter_code>_X = np.array(
    [[1, 2, 3, 4],
     [5, 6, 7, 8]])
X = tf.convert_to_tensor(_X)

outs = [tf.reduce_sum(X),
        tf.reduce_sum(X, axis=0),
        tf.reduce_sum(X, axis=1, keep_dims=True),
        "",
        tf.reduce_prod(X),
        tf.reduce_prod(X, axis=0),
        tf.reduce_prod(X, axis=1, keep_dims=True),
        "",
        tf.reduce_min(X),
        tf.reduce_min(X, axis=0),
        tf.reduce_min(X, axis=1, keep_dims=True),
        "",
        tf.reduce_max(X),
        tf.reduce_max(X, axis=0),
        tf.reduce_max(X, axis=1, keep_dims=True),
        "",
        tf.reduce_mean(X),
        tf.reduce_mean(X, axis=0),
        tf.reduce_mean(X, axis=1, keep_dims=True)
           ]
           
for out in outs:
    if out == "":
        print()
    else:
        print("->", out.eval())
# If you remove the common suffix "reduce_", you will get the same 
# result in numpy.<jupyter_output>-> 36
-> [ 6  8 10 12]
-> [[10]
 [26]]

-> 40320
-> [ 5 12 21 32]
-> [[  24]
 [1680]]

-> 1
-> [1 2 3 4]
-> [[1]
 [5]]

-> 8
-> [5 6 7 8]
-> [[4]
 [8]]

-> 4
-> [3 4 5 6]
-> [[2]
 [6]]<jupyter_text>Q15. Predict the results of these.<jupyter_code>_X = np.array([[True, True],
              [False, False]], np.bool)
X = tf.convert_to_tensor(_X)

outs = [tf.reduce_all(X),
        tf.reduce_all(X, axis=0),
        tf.reduce_all(X, axis=1, keep_dims=True),
        "",
        tf.reduce_any(X),
        tf.reduce_any(X, axis=0),
        tf.reduce_any(X, axis=1, keep_dims=True),
        ]

for out in outs:
    if out == "":
        print()
    else:
        print("->", out.eval())

# If you remove the common suffix "reduce_", you will get the same 
# result in numpy.<jupyter_output>-> False
-> [False False]
-> [[ True]
 [False]]

-> True
-> [ True  True]
-> [[ True]
 [False]]<jupyter_text>Q16. Predict the results of these.<jupyter_code>_X = np.array([[0, 1, 0],
              [1, 1, 0]])
X = tf.convert_to_tensor(_X)

outs = [tf.count_nonzero(X),
        tf.count_nonzero(X, axis=0),
        tf.count_nonzero(X, axis=1, keep_dims=True),
        ]

for out in outs:
    print("->", out.eval())

# tf.count_nonzero == np.count_nonzero<jupyter_output>-> 3
-> [1 2 0]
-> [[1]
 [2]]<jupyter_text>Q17. Complete the einsum function that would yield the same result as the given function.<jupyter_code>_X = np.arange(1, 7).reshape((2, 3))
_Y = np.arange(1, 7).reshape((3, 2))

X = tf.convert_to_tensor(_X)
Y = tf.convert_to_tensor(_Y)

# Matrix multiplication
out1 = tf.matmul(X, Y)
out1_ = tf.einsum('ij,jk->ik', X, Y)
assert np.allclose(out1.eval(), out1_.eval())

# Dot product
flattened = tf.reshape(X, [-1])
out2 = tf.reduce_sum(flattened * flattened)
out2_ = tf.einsum('i,i->', flattened, flattened)
assert np.allclose(out2.eval(), out2_.eval())

# Outer product
expanded_a = tf.expand_dims(flattened, 1) # shape: (6, 1)
expanded_b = tf.expand_dims(flattened, 0) # shape: (1, 6)
out3 = tf.matmul(expanded_a, expanded_b)
out3_ = tf.einsum('i,j->ij', flattened, flattened)
assert np.allclose(out3.eval(), out3_.eval())

# Transpose
out4 = tf.transpose(X) # shape: (3, 2)
out4_ = tf.einsum('ij->ji', X)
assert np.allclose(out4.eval(), out4_.eval())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1831035288618836, 'fraction_numerical': 0.05258237906052816, 'mean_word_length': 3.6643051771117165, 'pattern_counts': {'":': 2, '<': 57, '<?xml version=': 0, '>': 88, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '591559', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3972, 'n_tokens_neox': 3669, 'n_words': 858, 'path': 'Math_Part2_Solutions.ipynb', 'repo_name': 'arikolsh/tensorflow-exercises', 'size': '8558'}