diff --git a/your-code/main.ipynb b/your-code/main.ipynb index 46f5aa14..5dfaa28e 100644 --- a/your-code/main.ipynb +++ b/your-code/main.ipynb @@ -16,11 +16,12 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "### [your code here]\n" + "import numpy as np\n", + "\n" ] }, { @@ -34,11 +35,91 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.1.3\n", + "Build Dependencies:\n", + " blas:\n", + " detection method: pkgconfig\n", + " found: true\n", + " include directory: C:/Users/BOSCO/anaconda3/Library/include\n", + " lib directory: C:/Users/BOSCO/anaconda3/Library/lib\n", + " name: mkl-sdl\n", + " openblas configuration: unknown\n", + " pc file directory: C:\\b\\abs_25aj347ekn\\croot\\numpy_and_numpy_base_1730835595898\\_h_env\\Library\\lib\\pkgconfig\n", + " version: '2023.1'\n", + " lapack:\n", + " detection method: pkgconfig\n", + " found: true\n", + " include directory: C:/Users/BOSCO/anaconda3/Library/include\n", + " lib directory: C:/Users/BOSCO/anaconda3/Library/lib\n", + " name: mkl-sdl\n", + " openblas configuration: unknown\n", + " pc file directory: C:\\b\\abs_25aj347ekn\\croot\\numpy_and_numpy_base_1730835595898\\_h_env\\Library\\lib\\pkgconfig\n", + " version: '2023.1'\n", + "Compilers:\n", + " c:\n", + " commands: cl.exe\n", + " linker: link\n", + " name: msvc\n", + " version: 19.29.30156\n", + " c++:\n", + " commands: cl.exe\n", + " linker: link\n", + " name: msvc\n", + " version: 19.29.30156\n", + " cython:\n", + " commands: cython\n", + " linker: cython\n", + " name: cython\n", + " version: 3.0.11\n", + "Machine Information:\n", + " build:\n", + " cpu: x86_64\n", + " endian: little\n", + " family: x86_64\n", + " system: windows\n", + " host:\n", + " cpu: x86_64\n", + " endian: little\n", + " family: x86_64\n", + " system: windows\n", + "Python Information:\n", + " path: C:\\b\\abs_25aj347ekn\\croot\\numpy_and_numpy_base_1730835595898\\_h_env\\python.exe\n", + " version: '3.13'\n", + "SIMD Extensions:\n", + " baseline:\n", + " - SSE\n", + " - SSE2\n", + " - SSE3\n", + " found:\n", + " - SSSE3\n", + " - SSE41\n", + " - POPCNT\n", + " - SSE42\n", + " - AVX\n", + " - F16C\n", + " - FMA3\n", + " - AVX2\n", + " not found:\n", + " - AVX512F\n", + " - AVX512CD\n", + " - AVX512_SKX\n", + " - AVX512_CLX\n", + " - AVX512_CNL\n", + " - AVX512_ICL\n", + "\n" + ] + } + ], + "source": [ + "print(np.__version__)\n", + "np.show_config()" ] }, { @@ -51,11 +132,11 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "### [your code here]\n" + "a = np.random.rand(2, 3, 5) # 3D array of shape (2, 3, 5) filled with random floats uniformly sampled in [0, 1)\n" ] }, { @@ -68,11 +149,27 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[0.10618736 0.61434653 0.24294772 0.1577766 0.70124103]\n", + " [0.10698764 0.37137472 0.93062496 0.29187348 0.15754918]\n", + " [0.7000129 0.89703946 0.69376316 0.96046023 0.97386272]]\n", + "\n", + " [[0.75468747 0.93264771 0.6993988 0.02654417 0.71575266]\n", + " [0.52513858 0.12160953 0.75539478 0.90778362 0.1952423 ]\n", + " [0.29019675 0.97390315 0.78107759 0.01423088 0.16915963]]]\n", + "(2, 3, 5)\n" + ] + } + ], + "source": [ + "print(a)\n", + "print(a.shape) \n" ] }, { @@ -85,11 +182,14 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "### [your code here]\n" + "b = np.ones((5, 2, 3)) # The shape (5, 2, 3) means:\n", + " # 5 blocks (or \"matrices\")\n", + " # each block has 2 rows\n", + " # and each row has 3 columns" ] }, { @@ -102,11 +202,34 @@ }, { "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[1. 1. 1.]\n", + " [1. 1. 1.]]\n", + "\n", + " [[1. 1. 1.]\n", + " [1. 1. 1.]]\n", + "\n", + " [[1. 1. 1.]\n", + " [1. 1. 1.]]\n", + "\n", + " [[1. 1. 1.]\n", + " [1. 1. 1.]]\n", + "\n", + " [[1. 1. 1.]\n", + " [1. 1. 1.]]]\n", + "(5, 2, 3)\n" + ] + } + ], + "source": [ + "print(b) \n", + "print(b.shape) " ] }, { @@ -119,11 +242,24 @@ }, { "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "30\n", + "30\n", + "True\n" + ] + } + ], + "source": [ + "print(a.size) # .size gives the total count of elements in array 'a'\n", + "print(b.size) # \" \"\n", + "\n", + "print(a.size == b.size) # Compares both sizes; returns True if they have the same number of elements\n" ] }, { @@ -131,16 +267,34 @@ "metadata": {}, "source": [ "\n", - "### 8. Are you able to add a and b? Why or why not?\n" + "### 8. # --- Check shapes and try to add arrays 'a' and 'b' ---\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 3, 5)\n", + "(5, 2, 3)\n", + "Addition failed: operands could not be broadcast together with shapes (2,3,5) (5,2,3) \n" + ] + } + ], + "source": [ + "print(a.shape) \n", + "print(b.shape) \n", + "\n", + "try:\n", + " c = a + b\n", + " print(\"Addition succeeded.\")\n", + "except ValueError as e: # e stores the error message object into variable 'e',\n", + " print(\"Addition failed:\", e) #this will show incopatibiliy of shapes and so why addition failed\n" ] }, { @@ -154,11 +308,33 @@ }, { "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(5, 2, 3)\n", + "(2, 3, 5)\n" + ] + } + ], + "source": [ + "print(b.shape) # (5, 2, 3) - 5 blocks, each with 2 rows and 3 columns\n", + "\n", + "# The goal: make it look like 'a', which has shape (2, 3, 5)\n", + "# That means we want: 2 blocks, each with 3 rows and 5 columns.\n", + "# To do this, we must reorder the axes of 'b'.\n", + "\n", + "c = np.transpose(b, (1, 2, 0)) # np.transpose reorders the *axes* of the array.\n", + " # The tuple (1, 2, 0) means:\n", + " # - The 0th axis (size 5) of 'b' moves to the 3rd position (2nd axis).\n", + " # - The 1st axis (size 2) becomes the 0th axis in the new array.\n", + " # - The 2nd axis (size 3) becomes the 1st axis in the new array.\n", + " # So the resulting shape is (2, 3, 5).\n", + "\n", + "print(c.shape) # c should now have shape (2, 3, 5)\n" ] }, { @@ -171,11 +347,34 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 3, 5)\n", + "(2, 3, 5)\n", + "[[[1.10618736 1.61434653 1.24294772 1.1577766 1.70124103]\n", + " [1.10698764 1.37137472 1.93062496 1.29187348 1.15754918]\n", + " [1.7000129 1.89703946 1.69376316 1.96046023 1.97386272]]\n", + "\n", + " [[1.75468747 1.93264771 1.6993988 1.02654417 1.71575266]\n", + " [1.52513858 1.12160953 1.75539478 1.90778362 1.1952423 ]\n", + " [1.29019675 1.97390315 1.78107759 1.01423088 1.16915963]]]\n", + "(2, 3, 5)\n" + ] + } + ], + "source": [ + "print(a.shape) # (2, 3, 5)\n", + "print(c.shape) # (2, 3, 5)\n", + "\n", + "d = a + c # both arrays now have exactly the same shape, every element in 'a' has a matching element in 'c', therefore broadcasting should work perfectly (no stretching or mismatch)\n", + "\n", + "print(d) \n", + "print(d.shape) " ] }, { @@ -188,12 +387,40 @@ }, { "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n", - "\n" + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[0.10618736 0.61434653 0.24294772 0.1577766 0.70124103]\n", + " [0.10698764 0.37137472 0.93062496 0.29187348 0.15754918]\n", + " [0.7000129 0.89703946 0.69376316 0.96046023 0.97386272]]\n", + "\n", + " [[0.75468747 0.93264771 0.6993988 0.02654417 0.71575266]\n", + " [0.52513858 0.12160953 0.75539478 0.90778362 0.1952423 ]\n", + " [0.29019675 0.97390315 0.78107759 0.01423088 0.16915963]]]\n", + "[[[1.10618736 1.61434653 1.24294772 1.1577766 1.70124103]\n", + " [1.10698764 1.37137472 1.93062496 1.29187348 1.15754918]\n", + " [1.7000129 1.89703946 1.69376316 1.96046023 1.97386272]]\n", + "\n", + " [[1.75468747 1.93264771 1.6993988 1.02654417 1.71575266]\n", + " [1.52513858 1.12160953 1.75539478 1.90778362 1.1952423 ]\n", + " [1.29019675 1.97390315 1.78107759 1.01423088 1.16915963]]]\n", + "\n", + "Check if d = a + 1 everywhere:\n", + "True\n" + ] + } + ], + "source": [ + "print(a) \n", + "print(d) \n", + "\n", + "print(\"\\nCheck if d = a + 1 everywhere:\") # The '\\n' at the start of the string means \"newline\", so output will look cleaner, separating this message from previous prints.\n", + " # The rest of the text 'Check if d = a + 1 everywhere:' just string of wrriten ouput.\n", + "print(np.allclose(d, a + 1)) # Returns True if every element of d equals element of a + 1\n" ] }, { @@ -206,11 +433,28 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[0.10618736 0.61434653 0.24294772 0.1577766 0.70124103]\n", + " [0.10698764 0.37137472 0.93062496 0.29187348 0.15754918]\n", + " [0.7000129 0.89703946 0.69376316 0.96046023 0.97386272]]\n", + "\n", + " [[0.75468747 0.93264771 0.6993988 0.02654417 0.71575266]\n", + " [0.52513858 0.12160953 0.75539478 0.90778362 0.1952423 ]\n", + " [0.29019675 0.97390315 0.78107759 0.01423088 0.16915963]]]\n", + "(2, 3, 5)\n" + ] + } + ], + "source": [ + "e = a * c\n", + "print(e) \n", + "print(e.shape) " ] }, { @@ -224,12 +468,31 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n", - "\n" + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n" + ] + } + ], + "source": [ + "print(np.array_equal(e, a)) # np.array_equal() checks whether two NumPy arrays have:\n", + " # If both are identical, it returns True; otherwise, False.\n", + " # In this case:\n", + " # e was created by multiplying a * c\n", + " # and c is an array full of ones (shape (2, 3, 5)) - so each element of 'a' was multiplied by 1, so e[i,j,k] = a[i,j,k] × 1 = a[i,j,k]\n", + " # Therefore, the result should be True, thiswould then mean the arrays are *exactly equal* in both content and structure.\n", + "\n", + "print(np.allclose(e, a)) # np.allclose() does a similar comparison but allows for small rounding errors.\n", + " # It is very useful in situations when dealing with floating-point numbers, since operations, like addition or multiplication can introduce tiny precision differences.\n", + " # Here, since we multiplied by 1, even floating-point rounding shouldn’t change anything, so this should also print True.\n", + "\n", + "# Conclusion: if both checks come true it means, 'e' and 'a' are identical in both value and shape." ] }, { @@ -243,11 +506,33 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 19, "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Maximum value in d: 1.9739031525087232\n", + "Minimum value in d: 1.0142308838715621\n", + "Mean value in d: 1.5256271774963193\n" + ] + } + ], + "source": [ + "d_max = d.max() # .max() finds the *largest* (maximum) value in the entire array 'd'.\n", + " # It scans through every element of 'd' (since we didn’t specify an axis), and returns the single highest number found.\n", + " # The result is stored in the variable 'd_max'.\n", + "\n", + "d_min = d.min() # .min() finds the *smallest* (minimum) value in the array 'd'.\n", + " # It works the same way as .max(), but returns the lowest number instead.\n", + " # The result is stored in the variable 'd_min'.\n", + "\n", + "d_mean = d.mean() # .mean() computes the *average* \n", + "\n", + "print(\"Maximum value in d:\", d_max) \n", + "print(\"Minimum value in d:\", d_min) \n", + "print(\"Mean value in d:\", d_mean) \n", "\n" ] }, @@ -261,11 +546,38 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 20, "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 3, 5)\n", + "[[[1.07187361e-06 6.15346529e-06 2.43947723e-06 1.58776604e-06\n", + " 7.02241028e-06]\n", + " [1.07987644e-06 3.72374723e-06 9.31624962e-06 2.92873478e-06\n", + " 1.58549183e-06]\n", + " [7.01012898e-06 8.98039465e-06 6.94763159e-06 9.61460228e-06\n", + " 9.74862725e-06]]\n", + "\n", + " [[7.55687472e-06 9.33647706e-06 7.00398801e-06 2.75441652e-07\n", + " 7.16752657e-06]\n", + " [5.26138579e-06 1.22609530e-06 7.56394784e-06 9.08783624e-06\n", + " 1.96242299e-06]\n", + " [2.91196752e-06 9.74903153e-06 7.82077586e-06 1.52308839e-07\n", + " 1.70159625e-06]]]\n" + ] + } + ], + "source": [ + "f = np.empty(d.shape) # np.empty() creates a new NumPy array *without initializing its values*, it allocates a block of memory of the requested shape and dtype.\n", + " # The contents of this memory are unpredictable — they might contain leftover, numbers from previous computations (whatever was in memory at that location).\n", + " # The argument 'd.shape' tells NumPy: \"create an array with exactly the same dimensions as 'd'\".\n", + " # Since d.shape = (2, 3, 5), f will also have shape (2, 3, 5).\n", + "\n", + "print(f.shape) \n", + "print(f) " ] }, { @@ -287,11 +599,51 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 21, "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[ 25. 75. 25. 25. 75.]\n", + " [ 25. 25. 75. 25. 25.]\n", + " [ 75. 75. 75. 75. 75.]]\n", + "\n", + " [[ 75. 75. 75. 25. 75.]\n", + " [ 25. 25. 75. 75. 25.]\n", + " [ 25. 100. 75. 0. 25.]]]\n" + ] + } + ], + "source": [ + "f = np.empty(d.shape) # 'f' will store the label values (0, 25, 50, 75, or 100)\n", + " # three nested loops - iterate through every element of the 3D array 'd'.\n", + "\n", + "for i in range(d.shape[0]): # Outer loop over the first dimension (0 to 1, because there are 2 blocks)\n", + " for j in range(d.shape[1]): # Middle loop over the second dimension (0 to 2, because there are 3 rows)\n", + " for k in range(d.shape[2]): # Inner loop over the third dimension (0 to 4, because there are 5 columns)\n", + " \n", + " value = d[i, j, k] # Retrieve the current value from 'd'\n", + " \n", + " if value == d_min: # If the current element is equal to the minimum value of 'd'\n", + " f[i, j, k] = 0 # Assign 0 to the same position in 'f'\n", + "\n", + " elif value == d_max: # If the element equals the maximum value of 'd'\n", + " f[i, j, k] = 100 # Assign 100 to that position in 'f'\n", + "\n", + " elif value == d_mean: # If the element equals the mean value of 'd'\n", + " f[i, j, k] = 50 # Assign 50 to that position in 'f'\n", + "\n", + " elif d_min < value < d_mean: # If the element is between the minimum and the mean (exclusive)\n", + " f[i, j, k] = 25 # Assign 25 to that position in 'f'\n", + "\n", + " elif d_mean < value < d_max: # If the element is between the mean and the maximum (exclusive)\n", + " f[i, j, k] = 75 # Assign 75 to that position in 'f'\n", + "\n", + "# After all the loops finish, 'f' will be completely filled.\n", + "\n", + "print(f)\n" ] }, { @@ -325,11 +677,42 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 22, "metadata": {}, - "outputs": [], - "source": [ - "### [your code here]\n" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[1.10618736 1.61434653 1.24294772 1.1577766 1.70124103]\n", + " [1.10698764 1.37137472 1.93062496 1.29187348 1.15754918]\n", + " [1.7000129 1.89703946 1.69376316 1.96046023 1.97386272]]\n", + "\n", + " [[1.75468747 1.93264771 1.6993988 1.02654417 1.71575266]\n", + " [1.52513858 1.12160953 1.75539478 1.90778362 1.1952423 ]\n", + " [1.29019675 1.97390315 1.78107759 1.01423088 1.16915963]]]\n", + "[[[ 25. 75. 25. 25. 75.]\n", + " [ 25. 25. 75. 25. 25.]\n", + " [ 75. 75. 75. 75. 75.]]\n", + "\n", + " [[ 75. 75. 75. 25. 75.]\n", + " [ 25. 25. 75. 75. 25.]\n", + " [ 25. 100. 75. 0. 25.]]]\n", + "[ 0. 25. 75. 100.]\n" + ] + } + ], + "source": [ + "print(d) \n", + "print(f) # This prints the array of *labels* created in question 16.\n", + " # Each position in 'f' corresponds to the same index in 'd'.\n", + " # The labels represent ranges relative to d_min, d_mean, and d_max:\n", + " # 0 → elements equal to d_min\n", + " # 25 → elements between d_min and d_mean\n", + " # 50 → elements exactly equal to d_mean\n", + " # 75 → elements between d_mean and d_max\n", + " # 100 → elements equal to d_max\n", + "print(np.unique(f))\n" ] }, { @@ -360,7 +743,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "base", "language": "python", "name": "python3" }, @@ -374,7 +757,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.0" + "version": "3.13.5" } }, "nbformat": 4,