Files
wehub-resource-sync 26446540fa
Lint / lint (push) Waiting to run
CI / MacOS (push) Waiting to run
CI / Windows (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:25 +08:00

86 lines
2.8 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# pylint: disable=invalid-name
"""MatrixSetDiag in Python"""
import numpy as np
def matrix_set_diag(input_np, diagonal, k=0, align="RIGHT_LEFT"):
"""matrix_set_diag operator implemented in numpy.
Returns a numpy array with the diagonals of input array
replaced with the provided diagonal values.
Parameters
----------
input_np : numpy.ndarray
Input Array.
Shape = [D1, D2, D3, ... , Dn-1 , Dn]
diagonal : numpy.ndarray
Values to be filled in the diagonal.
k : int or tuple of int
Diagonal Offsets.
align : string
Some diagonals are shorter than max_diag_len and need to be padded.
Possible Vales:
["RIGHT_LEFT" (default), "LEFT_RIGHT", "LEFT_LEFT", "RIGHT_RIGHT"]
Returns
-------
result : numpy.ndarray
New Array with given diagonal values.
Shape = [D1, D2, D3, ... , Dn-1 , Dn]
"""
out = np.array(input_np, copy=True)
cols = input_np.shape[-1]
rows = input_np.shape[-2]
onlyOneDiagonal = True
if isinstance(k, tuple | list):
if len(k) < 2 or k[0] == k[1]:
k = k[0]
else:
onlyOneDiagonal = False
if onlyOneDiagonal:
for i in range(diagonal.shape[-1]):
if k >= 0:
out[..., i, i + k] = diagonal[..., i]
else:
out[..., i - k, i] = diagonal[..., i]
else:
for ki in range(k[0], k[1] + 1):
diag_len = min(cols - max(ki, 0), rows + min(ki, 0))
offset = 0
if ki >= 0:
if align[:5] == "RIGHT":
offset = diagonal.shape[-1] - diag_len
else:
if align[-5:] == "RIGHT":
offset = diagonal.shape[-1] - diag_len
for i in range(diag_len):
if ki >= 0:
out[..., i, i + ki] = diagonal[..., k[1] - ki, i + offset]
else:
out[..., i - ki, i] = diagonal[..., k[1] - ki, i + offset]
return out