Vector 에 대한 reshape 구현이다.
추후에 수정할거 있으면 수정해보기!!! (오류 검토 못해봄)
val a:Vector = new Vector(Array(1,2,3,4,5,6))
//i번째 인덱스부터 n개씩 나눠진 Array 반환하기
def sep(i:Int,n:Int):Array[Float]
def func(x:Array[Float], shape:Int*):NDArray= {
def sep(i:Int,n:Int,res:Array[Float]=Array()):Array[Float] ={
if(n==0) res
else sep(i+1,n-1,res ++ Array(x(i)))
}
if(shape.length ==1) new Vector(x)
else if (shape.length ==2) {
val res:Array[Vector] = Array()
for(x<- 1to shape(0)) {
val a = new Vector(sep((x-1)*shape(1),shape(1)))
res ++ Array(a)
}
//res 는 Array(Vector)
new Matrix(res)
}
else {
//3차원 이상은 수정하기
new Vector(x)
}
}
다음은 reduceLeft 이다.
/**
* Apply an element-wise binary operator to all elements along the first axis.
* Note that f can be non-associative.
*
* e.g) [[2, 3, 5], [3, 1, 0]].reduceLeft(_ + _) = [5, 4, 5]
* [[1, 2, 3]].reduceLeft(_ + _) = [1, 2, 3]
* [2, 3, 4].reduceLeft(_ - _) = ((2 - 3) - 4) = -5
*
* @param f binary operator
* @tparam T type of the inner element: NDArray (if this is Matrix or StackedArray) or Float (if this is Vector)
* @return see Seq.reduceLeft
*/
def reduceLeft[T](f: (Float, Float) => Float): T = ???
* Apply an element-wise binary operator to all elements along the first axis.
* Note that f can be non-associative.
* e.g)
예시 코드를 분석해보니 shape(0) 갯수만큼이 연산을 거치는 원소들.
* [[2, 3, 5], [3, 1, 0]].reduceLeft(_ + _) = [5, 4, 5]
해석 ) shape = (2,3) 인 Matrix
* [[1, 2, 3]].reduceLeft(_ + _) = [1, 2, 3]
해석 ) shape = (1,3)인 Matrix
* [2, 3, 4].reduceLeft(_ - _) = ((2 - 3) - 4) = -5
해석 ) shape = (3)인 Vector
*
* @param f binary operator
* @tparam T type of the inner element: NDArray (if this is Matrix or StackedArray) or Float (if this is Vector)
* @return see Seq.reduceLeft
*/
근데 지금은 벡터의 연산을 구현하는 것이므로 벡터, reduceLeft만 구현하면 된다.
def reduceLeft[T](f: (Float, Float) => Float): T = ???
// [2, 3, 4].reduceLeft(_ - _) = ((2 - 3) - 4) = -5
// [2, 3, 4].reduceLeft(_ - _) = ((2 - 3) - 4) = -5
def reduceLeft[T](f: (Float, Float) => Float): T = {
def func(arr:Array[Float],idx:Int = 0,res:Float =0):Float ={
if (idx == arr.length) res
else func(arr,idx+1,f(res,arr(idx)))
}
func(this.values)
}
이렇게 코드 짜봤더니 func(this.values)가 T type이 아니고 Float type이라고 빨간줄 긋고 지랄한다...
* @tparam T type of the inner element: NDArray (Matrix or StackedArray) or Float (if this is Vector)
그럼 이건 뭔데....
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/045.gif)
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/017.gif)
def reduceLeft[T](f: (Float, Float) => Float): T = {
val a:Array[T] = Array()
def func(arr: Array[Float], idx: Int = 0, res: Float = 0): Float = {
if (idx == arr.length) res
else func(arr, idx + 1, f(res, arr(idx)))
}
a ++ Array(func(this.values))
a(0)
}
이렇게 고치니까 고요해졌긴한데 조금 더 지켜봐야겠다.....
unary operaion 구현하는 코드
def unaryOp(f: Float => Float): NDArray = {
val original: Array[Float] = this.values
def update(idx: Int, res: Array[Float]): Array[Float] = {
if (idx == original.length) res
else {
res(idx) = f(res(idx))
update(idx + 1, res)
}
}
val result:Vector = new Vector(update(0,original))
result
}
def binOp(f: (Float, Float) => Float, that: NDArray): NDArray = {
val original:Array[Float] = this.values
def update(idx:Int, res:Array[Float]):Array[Float] ={
if(idx == original.length) res
else {
res(idx) = f(that.get(idx),res(idx))
update(idx+1,res)
}
}
if(that.ndim != 1) throw new NNException("dims are not same")
else{
val result = new Vector(update(0,original))
result
}
}
def equals(that: NDArray): Boolean = {
def check(idx: Int): Boolean = {
if (idx >= values.length) true
else {
if (values(idx) != that.get(idx)) false
else check(idx + 1)
}
}
check(0)
}
일단 Vector.scala 는 마무리
... Matrix.scala 로 가보자
'학교 공부 > 프로그래밍원리' 카테고리의 다른 글
HW3 -(4) StackedArray 구현하기 (0) | 2022.11.27 |
---|---|
HW3 - (3) Matrix 구현하기 (0) | 2022.11.26 |
HW3 - (1) (0) | 2022.11.25 |
1122 Stacking with Type Classes (0) | 2022.11.22 |
11/16 Type Classes With Multiple Parameters & Higher-kind (0) | 2022.11.15 |