// Copyright 2025 International Digital Economy Academy
//
// Licensed 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.
///|
struct RowDVector {
data : Array[@core.Real]
start : Int
len : Int
}
///|
struct DVector {
data : Array[@core.Real]
start : Int
len : Int
}
///|
fn RowDVector::new_view(
data : Array[@core.Real],
start : Int,
len : Int,
) -> RowDVector {
{ data, start, len }
}
///|
fn DVector::new_view(
data : Array[@core.Real],
start : Int,
len : Int,
) -> DVector {
{ data, start, len }
}
///|
fn RowDVector::value_at(self : RowDVector, index : Int) -> @core.Real {
self.data[self.start + index]
}
///|
fn RowDVector::set_value(
self : RowDVector,
index : Int,
value : @core.Real,
) -> Unit {
self.data[self.start + index] = value
}
///|
fn DVector::value_at(self : DVector, index : Int) -> @core.Real {
self.data[self.start + index]
}
///|
fn DVector::set_value(self : DVector, index : Int, value : @core.Real) -> Unit {
self.data[self.start + index] = value
}
///|
pub fn RowDVector::from_fn(
size : Int,
init : (Int) -> @core.Real,
) -> RowDVector {
let values : Array[@core.Real] = []
for i in 0.. RowDVector {
RowDVector::new_view(values, 0, values.length())
}
///|
pub fn DVector::from_fn(size : Int, init : (Int) -> @core.Real) -> DVector {
let values : Array[@core.Real] = []
for i in 0.. DVector {
DVector::new_view(values, 0, values.length())
}
///|
pub fn RowDVector::equals(self : RowDVector, other : RowDVector) -> Bool {
if self.len != other.len {
return false
}
for i in 0.. Bool {
if self.len != other.len {
return false
}
for i in 0.. Int {
self.len
}
///|
pub fn DVector::len(self : DVector) -> Int {
self.len
}
///|
pub fn DVector::as_array(self : DVector) -> Array[@core.Real] {
// Most DVectors we expose publicly are full views (start=0, len=data.length()).
// Fall back to a copy if this is a sub-view.
if self.start == 0 && self.len == self.data.length() {
self.data
} else {
let out : Array[@core.Real] = []
for i in 0.. RowDVector {
let values : Array[@core.Real] = []
for i in 0.. Unit {
for i in 0.. Int {
3
}
///|
pub fn Jacobian::zeros(size : Int) -> Jacobian {
let total = Jacobian::spatial_dim() * size
let data : Array[@core.Real] = []
for _ in 0.. Unit {
if self.cols == cols {
for i in 0.. Unit {
self.data[row * self.cols + col] = value
}
///|
pub fn Jacobian::value_at(self : Jacobian, row : Int, col : Int) -> @core.Real {
self.data[row * self.cols + col]
}
///|
pub fn Jacobian::cols(self : Jacobian) -> Int {
self.cols
}
///|
pub fn Jacobian::equals(self : Jacobian, other : Jacobian) -> Bool {
if self.cols != other.cols {
return false
}
if self.data.length() != other.data.length() {
return false
}
for i in 0.. IndexSequence {
{ first_to_remove: -1, index_map: [] }
}
///|
pub fn IndexSequence::remove(self : IndexSequence, index : Int) -> Unit {
if self.first_to_remove < 0 {
self.first_to_remove = index
}
}
///|
pub fn IndexSequence::keep(self : IndexSequence, index : Int) -> Unit {
if self.first_to_remove < 0 {
return
}
self.index_map.push(index)
}
///|
fn IndexSequence::dim_after_removal(
self : IndexSequence,
original_dim : Int,
) -> Int {
if self.first_to_remove < 0 {
original_dim
} else {
self.first_to_remove + self.index_map.length()
}
}
///|
pub fn IndexSequence::rearrange_columns(
self : IndexSequence,
vec : RowDVector,
keep_columns : Bool,
) -> Unit {
if self.first_to_remove < 0 {
return
}
let base = self.first_to_remove
let count = self.index_map.length()
let mut shift = 0
for source in self.index_map {
let target = base + shift
let value = vec.value_at(source)
vec.set_value(target, value)
shift = shift + 1
}
if keep_columns {
for i in (base + count).. Unit {
if self.first_to_remove < 0 {
return
}
let base = self.first_to_remove
let count = self.index_map.length()
let mut shift = 0
for source in self.index_map {
let target = base + shift
let value = vec.value_at(source)
vec.set_value(target, value)
shift = shift + 1
}
if keep_rows {
for i in (base + count).. Unit {
if self.first_to_remove < 0 {
return
}
let count = self.index_map.length()
for i in 0.. Unit,
) -> Unit {
self.rearrange_rows(vec, true)
let effective_dim = self.dim_after_removal(vec.len())
if effective_dim > 0 {
let view = DVector::new_view(vec.data, vec.start, effective_dim)
action(view)
}
self.inv_rearrange_rows(vec)
}