Special Matrices

# Identity Matrix

# Creates a 3x3 identity matrix
I3 = Matrix{Float64}(I, 3, 3)  # Explicitly specifying the type and size
println("3x3 Identity Matrix:\n", I3)

I4 = Diagonal(ones(4)) # Another way to create a 4x4 identity matrix
println("\n4x4 Identity Matrix (using Diagonal):\n", I4)


# Zero Matrix

# Creates a 2x4 zero matrix of Float64s
Z24 = zeros(Float64, 2, 4)
println("\n2x4 Zero Matrix:\n", Z24)

# Creates a 3x3 zero matrix of Ints (Julia defaults to Int if not specified)
Z33_int = zeros(Int, 3, 3)
println("\n3x3 Zero Matrix (Integers):\n", Z33_int)


# One Matrix

# Creates a 3x2 matrix of ones (Float64 by default)
O32 = ones(3, 2)
println("\n3x2 One Matrix:\n", O32)

# Creates a 4x4 matrix of ones (Integers)
O44_int = ones(Int, 4, 4)
println("\n4x4 One Matrix (Integers):\n", O44_int)


# Matrix of a specific value

# Creating a 5x5 matrix filled with the value 7.
M55_7 = fill(7.0, 5, 5) # Float64
println("\n5x5 Matrix filled with 7.0:\n", M55_7)

M23_neg5 = fill(-5, 2, 3)  # Int
println("\n2x3 Matrix filled with -5:\n", M23_neg5)


# Important Considerations and Best Practices:

# Type Stability: It's generally good practice to specify the element type of your matrices (e.g., Float64, Int). This improves performance, especially for larger matrices.
# Size: Be explicit about the dimensions of your matrices.
# `Matrix{}(I, n, n)`: This is a concise and efficient way to create an identity matrix of size `n x n` and a specified type.
# `Diagonal(ones(n))`:  A very efficient way to create an identity matrix, especially for larger sizes.
# `zeros()` and `ones()`: Use these functions to create matrices of zeros and ones, respectively.  Specify the type if needed.
# `fill(value, rows, cols)`: Use this to create a matrix where all elements have the same specified value.
# Printing: The `println()` function is used here for demonstration.  In more complex programs, you might use other methods for displaying or working with matrices.

This example demonstrates different ways to create these fundamental matrices, highlighting type considerations and best practices in Julia. Remember to choose the method that best suits your specific needs and always be mindful of the types of your matrix elements for optimal performance.