<jupyter_start><jupyter_text>Operationselementwise operations:scalar operation, some standard binary operator on each pair of corresponding elements from the two arrays, any function that maps from a scalar to a scalar.<jupyter_code>%%time
import torch<jupyter_output>Wall time: 1.32 s<jupyter_text>The common standard arithmetic operators (+, -, *, /, and **) have all been lifted to elementwise operations for any identically-shaped tensors of arbitrary shape.<jupyter_code>x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y  # The ** operator is exponentiation

z = torch.tensor([3, 4, 5, 6, 7])
z + y, z - y, z * y, z / y, z ** y  # The ** operator is ezponentiation
torch.exp(x)
x = torch.arange(12, dtype=torch.float32).reshape((3,4))
y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((x, y), dim=0), torch.cat((x, y), dim=1)<jupyter_output><empty_output><jupyter_text>construct a binary ndarray via logical statements.<jupyter_code>x == y
x < y
x > y
x.sum()
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b<jupyter_output><empty_output><jupyter_text>Since a and b are  3×1  and  1×2  matrices respectively, their shapes do not match up if we want to add them. We broadcast the entries of both matrices into a larger  3×2  matrix as follows: for matrix a it replicates the columns and for matrix b it replicates the rows before adding up both elementwise.<jupyter_code>a + b<jupyter_output><empty_output><jupyter_text>[-1] selects the last element and [1:3] selects the second and the third elements as follows:<jupyter_code>x[-1], x[1:3]
x[1, 2] = 9
x
x [0]
x[0:2, :] = 12
x<jupyter_output><empty_output><jupyter_text>Running operations can cause new memory to be allocated to host results.For example, if we write y = x + y, we will dereference the ndarray that y used to point to and instead point y at the newly allocated memory.<jupyter_code>before = id(y)
y = y + x
id(y) == before
id(x) < before
id(x) > before<jupyter_output><empty_output><jupyter_text>This might be undesirable for two reasons. 1. we do not want to run around allocating memory unnecessarily all the time. In machine learning, we might have hundreds of megabytes of parameters and update all of them multiple times per second. Typically, we will want to perform these updates in place. 2. we might point at the same parameters from multiple variables. If we do not update in place, other references will still point to the old memory location, making it possible for parts of our code to inadvertently reference stale parameters. We can assign the result of an operation to a previously allocated array with slice notation, e.g., y[:] = .<jupyter_code>z = torch.zeros_like(y)
print('id(z):', id(z))
z[:] = x + y
print('id(z):', id(z))<jupyter_output>id(z): 2584353511608
id(z): 2584353511608<jupyter_text>If the value of x is not reused in subsequent computations, we can also use x[:] = x + y or x += y to reduce the memory overhead of the operation.<jupyter_code>before = id(x)
x += y
id(x) == before
id(x) < before
id(x) > before
a = x.numpy()
b = torch.tensor(a)
type(a), type(b)<jupyter_output><empty_output><jupyter_text>Converting to a NumPy ndarray, or vice versa, is easy. The converted result does not share memory.<jupyter_code>a = x.numpy()
b = torch.tensor(a)
id(b) == id(a)
a = x.numpy()
before_a = id(a)
a = torch.tensor(a)
id(a) == before_a<jupyter_output><empty_output><jupyter_text>To convert a size-one ndarray to a Python scalar, we can invoke the item function or Python’s built-in functions.<jupyter_code>a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
x = torch.arange(12, dtype=torch.float32).reshape((3,4))
y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
x,y,x == y,x < y,x > y
a = torch.arange(1, 6, dtype =torch.float32).reshape((5, 1))
b = torch.arange(1, 3).reshape((1, 2))
a, b


a + b
a - b

a * b
a / b
a // b
a \ b
a ** b
a % b<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13148009015777612, 'fraction_numerical': 0.030803906836964687, 'mean_word_length': 4.738505747126437, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '428801', 'license': 'MIT', 'n_tokens_mistral': 1500, 'n_tokens_neox': 1419, 'n_words': 530, 'path': 'Ch02_Preliminaries/2-1-2.ipynb', 'repo_name': 'StevenJokess/d2l-en-read', 'size': '3993'}