;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; LUSH Lisp Universal Shell
;;;   Copyright (C) 2002 Leon Bottou, Yann Le Cun, AT&T Corp, NECI.
;;; Includes parts of TL3:
;;;   Copyright (C) 1987-1999 Leon Bottou and Neuristique.
;;; Includes selected parts of SN3.2:
;;;   Copyright (C) 1991-2001 AT&T Corp.
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software
;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; $Id: idx-squops.lsh,v 1.1 2002/08/19 07:01:28 profshadoko Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#? *** IDX operations on squares of elements
;; matrix and tensor operations that use
;; the squares of the elements. This is used primarily
;; for second derivative backpropagations in 
;; gradient-based learning algorithms.


;; stuff is in a handwritten C file for 
;; historical reasons. It should really be 
;; generated by the compiler.
(de idx-squops-dummy () (cheader "#include \"idxsquops.h\"") ())

#? (idx-m1squextm1 <m1> <m2> <m3>)
;; square outer product of <m1> and <m2>.
;; M3ij = M1i * M2j^2
(de idx-m1squextm1 (m1 m2 m3)
    ((-idx1- (-float-)) m1 m2)
    ((-idx2- (-float-)) m3)
    #{ Midx_m1squextm1($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m2squextm2 <m1> <m2> <m3>)
;; square outer product of <m1> and <m2>.
;; M3ijkl = M1ij * M2kl^2
(de idx-m2squextm2 (m1 m2 m3)
    ((-idx2- (-float-)) m1 m2)
    ((-idx4- (-float-)) m3)
    #{ Midx_m2squextm2($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m1squextm1acc <m1> <m2> <m3>)
;; square outer product of <m1> and <m2>.
;; M3ij += M1i * M2j^2
(de idx-m1squextm1acc (m1 m2 m3)
    ((-idx1- (-float-)) m1 m2)
    ((-idx2- (-float-)) m3)
    #{ Midx_m1squextm1acc($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m2squextm2acc <m1> <m2> <m3>)
;; square outer product of <m1> and <m2>.
;; M3ijkl += M1ij * M2kl^2
(de idx-m2squextm2acc (m1 m2 m3)
    ((-idx2- (-float-)) m1 m2)
    ((-idx4- (-float-)) m3)
    #{ Midx_m2squextm2acc($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m2squdotm1 <m1> <m2> <m3>)
;; multiply vector <m2> by matrix <m1>
;; using square of <m1> elements
;; M3i = sum_j M1ij^2 * M2j
(de idx-m2squdotm1 (m1 m2 m3)
    ((-idx2- (-float-)) m1)
    ((-idx1- (-float-)) m2 m3)
    #{ Midx_m2squdotm1($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m4squdotm2 <m1> <m2> <m3>)
;; multiply matrix <m2> by tensor <m1>
;; using square of <m1> elements
;; M3ij = sum_kl M1ijkl^2 * M2kl
(de idx-m4squdotm2 (m1 m2 m3)
    ((-idx4- (-float-)) m1)
    ((-idx2- (-float-)) m2 m3)
    #{ Midx_m4squdotm2($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m2squdotm1acc <m1> <m2> <m3>)
;; multiply vector <m2> by matrix <m1>
;; using square of <m1> elements
;; M3i += sum_j M1ij^2 * M2j
(de idx-m2squdotm1acc (m1 m2 m3)
    ((-idx2- (-float-)) m1)
    ((-idx1- (-float-)) m2 m3)
    #{ Midx_m2squdotm1acc($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m4squdotm2acc <m1> <m2> <m3>)
;; multiply matrix <m2> by tensor <m1>
;; using square of <m1> elements
;; M3ij += sum_kl M1ijkl^2 * M2kl
(de idx-m4squdotm2acc (m1 m2 m3)
    ((-idx4- (-float-)) m1)
    ((-idx2- (-float-)) m2 m3)
    #{ Midx_m4squdotm2acc($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m1squdotm1acc <m1> <m2> <m3>)
;; dot product between <m1> and <m2>, except
;; square of terms of <m1> are used:
;; M3 += sum_i M1i^2 * M2i
(de idx-m1squdotm1acc (m1 m2 m3)
    ((-idx1- (-float-)) m1 m2)
    ((-idx0- (-float-)) m3)
    #{ Midx_m1squdotm1acc($m1,$m2,$m3,float,float,float);
    #} ())

#? (idx-m2squdotm2acc <m1> <m2> <m3>)
;; dot product between matrices <m1> and 
;; <m2>, except square of terms of <m1> 
;; are used:
;; M3 += sum_ij M1ij^2 * M2ij
(de idx-m2squdotm2acc (m1 m2 m3)
    ((-idx2- (-float-)) m1 m2)
    ((-idx0- (-float-)) m3)
    #{ Midx_m2squdotm2acc($m1,$m2,$m3,float,float,float);
    #} ())

(dhc-make ()
	  idx-squops-dummy
	  idx_m1squextm1
	  idx_m2squextm2
	  idx_m1squextm1acc
	  idx_m2squextm2acc
	  idx_m2squdotm1
	  idx_m4squdotm2
	  idx_m2squdotm1acc
	  idx_m4squdotm2acc
	  idx_m1squdotm1acc
	  idx_m2squdotm2acc)
