import size from 'lodash-es/size.js'
import get from 'lodash-es/get.js'
import each from 'lodash-es/each.js'
import map from 'lodash-es/map.js'
import reverse from 'lodash-es/reverse.js'
import toNumber from 'lodash-es/toNumber.js'
import isNumber from 'lodash-es/isNumber.js'
import isnum from './isnum.mjs'
import isarr from './isarr.mjs'
import isestr from './isestr.mjs'
let inXRange = 'in x-range'
let outOfXRange = 'out of x-range'
let orderList = 'order list'
let reverseOrderList = 'reverse order list'
function toArrayX(ps, opt = {}) {
//若無數據回傳空陣列
if (size(ps) <= 0) {
return []
}
//keyX
let keyX = get(opt, 'keyX')
if (!isestr(keyX)) {
keyX = 'x'
}
//rs
let rs = []
each(ps, (v) => {
let x = null
if (isnum(v)) {
x = toNumber(v)
}
else if (isarr(v) && size(v) >= 1) {
x = get(v, 0)
}
else {
x = get(v, keyX, null)
}
if (isnum(x)) {
x = toNumber(x)
rs.push({
x,
})
}
})
return rs
}
function toArrayXY(ps, opt = {}) {
//若無數據回傳空陣列
if (size(ps) <= 0) {
return []
}
//keyX
let keyX = get(opt, 'keyX')
if (!isestr(keyX)) {
keyX = 'x'
}
//keyY
let keyY = get(opt, 'keyY')
if (!isestr(keyY)) {
keyY = 'y'
}
//rs
let rs = []
each(ps, (v) => {
let x = null
let y = null
if (isarr(v) && size(v) >= 2) {
x = get(v, 0)
y = get(v, 1)
}
else {
x = get(v, keyX, null)
y = get(v, keyY, null)
}
if (isnum(x) && isnum(y)) {
x = toNumber(x)
y = toNumber(y)
rs.push({
x,
y,
})
}
})
return rs
}
function checkTrend(ps) {
//check
let bOrder = true
let bReverseOrder = true
for (let i = 1; i < size(ps); i++) {
let p0 = ps[i - 1]
let p1 = ps[i]
if (bOrder && p0.x > p1.x) { //有遞減出現
bOrder = false
}
if (bReverseOrder && p0.x < p1.x) { //有遞增出現
bReverseOrder = false
}
if (p0.x === p1.x) {
return {
err: `x can not be equal: i=${i}, x=${p0.x}`
}
}
}
if (bOrder) {
return orderList
}
if (bReverseOrder) {
return reverseOrderList
}
return 'no'
}
function checkLimit(ps, x) {
//xmin, xmax, 外部已確保x為遞增
let xmin = null
let xmax = null
xmin = ps[0].x
xmax = ps[size(ps) - 1].x
//lt, less than lower limit
if (x < xmin) {
return {
err: outOfXRange,
msg: `x[${x}] less than lower limit[${xmin}]`,
data: {
ps,
x,
xmin,
xmax,
},
}
}
//gt, greater than upper limit
if (x > xmax) {
return {
err: outOfXRange,
msg: `x[${x}] greater than upper limit[${xmax}]`,
data: {
ps,
x,
xmin,
xmax,
},
}
}
return inXRange
}
function interp1Linear(ps, x) {
//尋找x對應y值, 採各點之間線性內插
//checkLimit
let cl = checkLimit(ps, x)
if (cl !== inXRange) {
return cl
}
//r
let r = null
for (let i = 1; i < size(ps); i++) {
let p0 = ps[i - 1]
let p1 = ps[i]
if (p0.x <= x && x <= p1.x) {
r = ((x - p0.x) * p1.y + (p1.x - x) * p0.y) / (p1.x - p0.x)
break
}
}
//check, 有檢核x是否超過上下限, 此處應該不會用到
if (r === null) {
return {
err: outOfXRange
}
}
return r
}
function interp1Stairs(ps, x, opt = {}) {
//每個點為bar中點, 尋找x所在之bar值(y)
//xMin, 擴充最小x值範圍
let xMin = get(opt, 'xMin')
if (isNumber(xMin)) {
//外部已確保x為遞增
if (xMin > ps[0].x) {
return {
err: `xMin=${xMin} > ps[0].x=${ps[0].x}`
}
}
else if (xMin === ps[0].x) {
//不用擴充
}
else {
let p = {
x: xMin,
y: ps[0].y, //使用第一筆數據y
}
ps = [p, ...ps] //遞增數據得添加xMin於最前
}
}
//xMax, 擴充最大x值範圍
let xMax = get(opt, 'xMax')
if (isNumber(xMax)) {
//外部已確保x為遞增
if (xMax < ps[size(ps) - 1].x) {
return {
err: `xMax=${xMax} < ps[size(ps)-1].x=${ps[size(ps) - 1].x}`
}
}
else if (xMax === ps[size(ps) - 1].x) {
//不用擴充
}
else {
let p = {
x: xMax,
y: ps[size(ps) - 1].y, //使用最後一筆數據y
}
ps = [...ps, p] //遞增數據得添加xMax於最後
}
}
//checkLimit
let cl = checkLimit(ps, x)
if (cl !== inXRange) {
return cl
}
//r
let r = null
for (let i = 0; i < size(ps); i++) {
let p0 = get(ps, i - 1, null)
let p1 = get(ps, i, null)
let p2 = get(ps, i + 1, null)
let x0 = p1.x
if (p0) {
x0 = (p0.x + p1.x) / 2 //若有前者, 則取前者與自己x的平均值作為起點
}
let x1 = p1.x
if (p2) {
x1 = (p2.x + p1.x) / 2 //若有後者, 則取後者與自己x的平均值作為終點
}
if (x0 <= x && x <= x1) {
r = p1.y
break
}
}
//check, 有檢核x是否超過上下限, 此處應該不會用到
if (r === null) {
return {
err: outOfXRange
}
}
return r
}
function interp1Blocks(ps, x) {
//第1點為起點, 其餘各點為各bar終點, 尋找x所在之bar值(y)
//checkLimit
let cl = checkLimit(ps, x)
if (cl !== inXRange) {
return cl
}
//r
let r = null
for (let i = 1; i < size(ps); i++) {
let p0 = ps[i - 1]
let p1 = ps[i]
let x0 = p0.x
let x1 = p1.x
if (x0 <= x && x <= x1) {
r = p1.y
break
}
}
//check, 有檢核x是否超過上下限, 此處應該不會用到
if (r === null) {
return {
err: outOfXRange
}
}
return r
}
/**
* 一維數據內插
*
* Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/interp1.test.mjs Github}
* @memberOf wsemi
* @param {Array} ps 輸入一維數據,格式可支援兩種,第一種各點為陣列[[x1,y1],[x2,y2],...],例如[[0.1,5],[0.2,12],...],第二種各點為物件,屬性至少要有x與y,格式為[{x:x1,y:y1},{x:x2,y:y2},...],例如[{x:0.1,y:5},{x:0.2,y:12},...],key值x與y可由opt更換
* @param {Number|Array} px 輸入要內插點的數值或數值陣列
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @param {String} [opt.mode=''] 輸入內插方法,可選'linear'、'stairs'、'blocks',預設'linear'
* @param {String} [opt.keyX='x'] 輸入若數據為物件陣列,取物件x值時的key字串,預設為'x'
* @param {String} [opt.keyY='y'] 輸入若數據為物件陣列,取物件y值時的key字串,預設為'y'
* @param {Number} [opt.xMin=undefined] 輸入若mode='stairs',更改x範圍下限值,預設為undefined
* @param {Number} [opt.xMax=undefined] 輸入若mode='stairs',更改x範圍上限值,預設為undefined
* @returns {Number|Object} 回傳內插結果數值,或是無法內插時之錯誤訊息物件
* @example
*
* let r
* let x
*
* let ps = [
* { x: 1, y: 0.2 },
* { x: 3, y: 1.2 },
* { x: 4, y: 2 },
* ]
*
* let psInv = [
* { x: 4, y: 2 },
* { x: 3, y: 1.2 },
* { x: 1, y: 0.2 },
* ]
*
* let psErr = [
* { x: 'a', y: 0.2 },
* { x: 'mnop', y: 1.2 },
* { x: 'xyz', y: 2 },
* ]
*
* let psEmpty = [
* ]
*
* let psEffOne = [
* { x: 1, y: 0.2 },
* { x: 'mnop', y: 1.2 },
* { x: 'xyz', y: 2 },
* ]
*
* let psP = [
* { a: 1, b: 0.2 },
* { a: 3, b: 1.2 },
* { a: 4, b: 2 },
* ]
*
* let px = [0, 1, 2, 2.6, 3, 3.5, 4, 5]
*
* let opt = {
* mode: 'stairs',
* }
*
* let optX = {
* mode: 'stairs',
* xMin: 0,
* xMax: 4.5,
* }
*
* let optP = {
* keyX: 'a',
* keyY: 'b',
* }
*
* x = 0
* r = interp1(psErr, x)
* console.log(`linear(error data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(error data): x=0 r={"err":"ps(length=0) is not an effective array","ps":[{"x":"a","y":0.2},{"x":"mnop","y":1.2},{"x":"xyz","y":2}],"psEff":[]}
*
* x = 0
* r = interp1(psEmpty, x)
* console.log(`linear(empty data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(empty data): x=0 r={"err":"ps(length=0) is not an effective array","ps":[],"psEff":[]}
*
* x = 0
* r = interp1(psEffOne, x)
* console.log(`linear(one point): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(one point): x=0 r={"err":"ps(length=1) is one point only","ps":[{"x":1,"y":0.2},{"x":"mnop","y":1.2},{"x":"xyz","y":2}],"psEff":[{"x":1,"y":0.2}]}
*
* x = 0
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=0 r={"err":"out of x-range","msg":"x[0] less than lower limit[1]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":0,"xmin":1,"xmax":4}}
*
* x = 1
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=1 r=0.2
*
* x = 2
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=2 r=0.7
*
* x = 2.6
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=2.6 r=1
*
* x = 3
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=3 r=1.2
*
* x = 3.5
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=3.5 r=1.6
*
* x = 4
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=4 r=2
*
* x = 5
* r = interp1(ps, x)
* console.log(`linear: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear: x=5 r={"err":"out of x-range","msg":"x[5] greater than upper limit[4]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":5,"xmin":1,"xmax":4}}
*
* x = 0
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=0 r={"err":"out of x-range","msg":"x[0] less than lower limit[1]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":0,"xmin":1,"xmax":4}}
*
* x = 1
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=1 r=0.2
*
* x = 2
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=2 r=0.7
*
* x = 2.6
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=2.6 r=1
*
* x = 3
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=3 r=1.2
*
* x = 3.5
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=3.5 r=1.6
*
* x = 4
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=4 r=2
*
* x = 5
* r = interp1(psInv, x)
* console.log(`linear(inverse data): x=${x}`, 'r=' + JSON.stringify(r))
* // => linear(inverse data): x=5 r={"err":"out of x-range","msg":"x[5] greater than upper limit[4]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":5,"xmin":1,"xmax":4}}
*
* x = -1
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=-1 r={"err":"out of x-range","msg":"x[-1] less than lower limit[1]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":-1,"xmin":1,"xmax":4}}
*
* x = 0.51
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=0.51 r={"err":"out of x-range","msg":"x[0.51] less than lower limit[1]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":0.51,"xmin":1,"xmax":4}}
*
* x = 1
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=1 r=0.2
*
* x = 1.9
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=1.9 r=0.2
*
* x = 2
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=2 r=0.2
*
* x = 2.1
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=2.1 r=1.2
*
* x = 2.5
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=2.5 r=1.2
*
* x = 3
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=3 r=1.2
*
* x = 3.49
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=3.49 r=1.2
*
* x = 3.5
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=3.5 r=1.2
*
* x = 3.51
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=3.51 r=2
*
* x = 4
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=4 r=2
*
* x = 4.5
* r = interp1(ps, x, opt)
* console.log(`stairs: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs: x=4.5 r={"err":"out of x-range","msg":"x[4.5] greater than upper limit[4]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":4.5,"xmin":1,"xmax":4}}
*
* x = -1
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=-1 r={"err":"out of x-range","msg":"x[-1] less than lower limit[0]","data":{"ps":[{"x":0,"y":0.2},{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2},{"x":4.5,"y":2}],"x":-1,"xmin":0,"xmax":4.5}}
*
* x = 0
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=0 r=0.2
*
* x = 0.49
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=0.49 r=0.2
*
* x = 0.5
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=0.5 r=0.2
*
* x = 0.51
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=0.51 r=0.2
*
* x = 1
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=1 r=0.2
*
* x = 1.9
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=1.9 r=0.2
*
* x = 2
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=2 r=0.2
*
* x = 2.1
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=2.1 r=1.2
*
* x = 2.5
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=2.5 r=1.2
*
* x = 3
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=3 r=1.2
*
* x = 3.49
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=3.49 r=1.2
*
* x = 3.5
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=3.5 r=1.2
*
* x = 3.51
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=3.51 r=2
*
* x = 4
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=4 r=2
*
* x = 4.49
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=4.49 r=2
*
* x = 4.5
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=4.5 r=2
*
* x = 4.51
* r = interp1(ps, x, optX)
* console.log(`stairs with x-limit: x=${x}`, 'r=' + JSON.stringify(r))
* // => stairs with x-limit: x=4.51 r={"err":"out of x-range","msg":"x[4.51] greater than upper limit[4.5]","data":{"ps":[{"x":0,"y":0.2},{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2},{"x":4.5,"y":2}],"x":4.51,"xmin":0,"xmax":4.5}}
*
* x = 0
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=0 r={"err":"out of x-range","msg":"x[0] less than lower limit[1]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":0,"xmin":1,"xmax":4}}
*
* x = 1
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=1 r=0.2
*
* x = 2
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=2 r=0.7
*
* x = 2.6
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=2.6 r=1
*
* x = 3
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=3 r=1.2
*
* x = 3.5
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=3.5 r=1.6
*
* x = 4
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=4 r=2
*
* x = 5
* r = interp1(psP, x, optP)
* console.log(`linear by keyX & keyY: x=${x}`, 'r=' + JSON.stringify(r))
* // => linear by keyX & keyY: x=5 r={"err":"out of x-range","msg":"x[5] greater than upper limit[4]","data":{"ps":[{"x":1,"y":0.2},{"x":3,"y":1.2},{"x":4,"y":2}],"x":5,"xmin":1,"xmax":4}}
*
* r = interp1(ps, px)
* console.log(`linear: px=${JSON.stringify(px)}`, 'r=' + JSON.stringify(r, null, 2))
* // => linear: px=[0,1,2,2.6,3,3.5,4,5] r=[
* // {
* // "err": "out of x-range",
* // "msg": "x[0] less than lower limit[1]",
* // "data": {
* // "ps": [
* // {
* // "x": 1,
* // "y": 0.2
* // },
* // {
* // "x": 3,
* // "y": 1.2
* // },
* // {
* // "x": 4,
* // "y": 2
* // }
* // ],
* // "x": 0,
* // "xmin": 1,
* // "xmax": 4
* // }
* // },
* // 0.2,
* // 0.7,
* // 1,
* // 1.2,
* // 1.6,
* // 2,
* // {
* // "err": "out of x-range",
* // "msg": "x[5] greater than upper limit[4]",
* // "data": {
* // "ps": [
* // {
* // "x": 1,
* // "y": 0.2
* // },
* // {
* // "x": 3,
* // "y": 1.2
* // },
* // {
* // "x": 4,
* // "y": 2
* // }
* // ],
* // "x": 5,
* // "xmin": 1,
* // "xmax": 4
* // }
* // }
* // ]
*
*/
function interp1(ps, px, opt = {}) {
//check ps
if (!isarr(ps)) {
return {
err: 'ps is not an array'
}
}
//check px
if (true) {
let b1 = !isnum(px)
let b2 = !isarr(px)
if (b1 && b2) {
return {
err: 'px is not a number or an array'
}
}
}
//toArrayXY
let psEff = toArrayXY(ps, opt)
// console.log('psEff', psEff)
//check
if (get(psEff, 'err')) {
return get(psEff, 'err')
}
//check
if (size(psEff) === 0) {
return {
err: 'ps(length=0) is not an effective array',
ps,
psEff,
}
}
else if (size(psEff) === 1) {
return {
err: 'ps(length=1) is one point only',
ps,
psEff,
}
}
//checkIncrea
let trend = checkTrend(psEff)
//check
if (trend === 'no') {
return {
err: 'psEff is not increasing or decreasing'
}
}
//反序
if (trend === reverseOrderList) {
trend = orderList
psEff = reverse(psEff)
}
//isOne
let isOne = !isarr(px)
// console.log('isOne', isOne)
//to array
if (isOne) {
px = [px]
}
//toArrayX
let pxEff = toArrayX(px, opt)
// console.log('pxEff', pxEff)
//mode
let mode = get(opt, 'mode')
if (mode !== 'linear' && mode !== 'stairs' && mode !== 'blocks') {
mode = 'linear'
}
//rs
let rs = map(pxEff, (o, ko) => {
let xEff = get(o, 'x')
// console.log(ko, o, xEff)
let v = null
try {
if (mode === 'linear') {
v = interp1Linear(psEff, xEff)
}
else if (mode === 'blocks') {
v = interp1Blocks(psEff, xEff)
}
else if (mode === 'stairs') {
v = interp1Stairs(psEff, xEff, opt)
}
}
catch (err) {
v = {
err: err.toString(),
}
}
return v
})
//r
let r
if (isOne) {
r = rs[0]
}
else {
r = rs
}
return r
}
export default interp1