load [file join [file dirname [info script]] structure.so]

proc matrix.* {a b} {
 set am [$a matrix]
 set bm [$b matrix]
 set r [list]
 set rrow [list]
 
 if {[$a columns] != [$b rows]} {
  return -code error "invalid matrix dimensions for multiply"
 }

 set bcoli 0 ; set browi 0
 set acoli 0 ; set arowi 0

 set amax [expr {[$a columns] * [$a rows]}]
 set bmax [expr {[$b columns] * [$b rows]}]

 
 if {$bmax > $amax} {
  set iter $bmax
 } else {
  set iter $amax
 }
 
 set i 0
 set tmp 0

 while {$i < $iter} {
  #puts "A:$arowi :: $acoli -- [$a rows] x [$a columns]"
  #puts "B:$browi :: $bcoli -- [$b rows] x [$b columns]"

  set adata [lindex $am $arowi $acoli]
  set bdata [lindex $bm $browi $bcoli]

  set tmp [expr {$tmp + ($adata * $bdata)}]

  incr acoli 
  if {$acoli >= [$a columns]} {
   set acoli 0
   incr arowi
   lappend rrow $tmp
   if {$arowi >= [$a rows]} {
    set arowi 0
    lappend r [list $rrow]
    set rrow [list]
   }
   set tmp 0
  }

  incr browi
  if {$browi >= [$b rows]} {
   set browi 0
   incr bcoli
  }

  incr i  
 }

 if {[llength $rrow]} {
  lappend r $rrow
 }
 matrix [llength $r] [llength [lindex $r 0]] $r
}

proc matrix {rows columns matrix} {
 set s [structure]

 $s \
   columns $columns \
   rows $rows \
   matrix $matrix \

 puts MATRIX:$matrix

 if {[llength $matrix] != $rows} {
  return -code error "matrix data doesn't match the specified rows: $rows"
 }


 if {[llength [lindex $matrix 0]] != $columns} {
  return -code error "matrix data doesn't match the specified columns: $columns"
 }

 return $s
}


set a [matrix 1 2 {
 {3 -2}
}] 

set b [matrix 2 1 {
 {4}
 {5}
}]

puts "2 == [[matrix.* $a $b] matrix]"

puts ----
set c [matrix 1 4 {
 {2 0 -1 1}
}]

set d [matrix 4 3 {
 {1 5 -7}
 {1 1  0}
 {0 -1 1}
 {2 0 0}
}]

puts "4 11 -15 == [[matrix.* $c $d] matrix]"
