@qudtlib/core
Version:
Data model for QUDTLib
1 lines • 8.31 kB
Source Map (JSON)
{"version":3,"sources":["dimensionVector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,cAAc,CAAC,eAAe,CAAC;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAE9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAE3B;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAElC,gBAAuB,aAAa,kBAEjC;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAK;IACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAK;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAK;IACzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAK;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IAEvC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAE5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;WAEzB,UAAU,CACtB,kBAAkB,EAAE,MAAM,GAAG,MAAM,EAAE,GACpC,eAAe;WAIJ,EAAE,CACd,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,GACjC,eAAe,GAAG,SAAS;gBAQlB,eAAe,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAanD,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,MAAM,CAAC,cAAc;IAO7B,OAAO,CAAC,MAAM,CAAC,SAAS;IAQjB,eAAe,IAAI,OAAO;IAI1B,qBAAqB,IAAI,MAAM;IAI/B,SAAS,IAAI,MAAM,EAAE;IAIrB,4BAA4B;IAG5B,0BAA0B;IAI1B,gBAAgB;IAGhB,4BAA4B;IAG5B,eAAe;IAGf,sBAAsB;IAGtB,eAAe;IAIf,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe;IAe5C,OAAO,CAAC,MAAM,CAAC,QAAQ;IAIhB,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe;IAehD,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;CAYnC","file":"dimensionVector.d.ts","sourcesContent":["import { QudtNamespaces } from \"./qudtNamespaces.js\";\nimport { isNullish } from \"./utils.js\";\nimport { SupportsEquals } from \"./baseTypes\";\n\n/**\n * Represents the QUDT dimension vector and allows for converting between a dimension vector IRI and\n * the numeric values, as well as for some manipulations.\n *\n * <p>Note that the last value, the 'D' dimension is special: it is only an indicator that the\n * dimension vector represents a ratio (causing all other dimensions to cancel each other out). It\n * never changes by multiplication, and its value is only 1 iff all other dimensions are 0.\n */\nexport class DimensionVector implements SupportsEquals<DimensionVector> {\n private static readonly DIMENSIONS = [\"A\", \"E\", \"L\", \"I\", \"M\", \"H\", \"T\", \"D\"];\n //public static final DecimalFormat FORMAT = new DecimalFormat(\"0.#\");\n private static readonly FORMAT = new Intl.NumberFormat(\"en-US\", {\n useGrouping: false,\n });\n private static readonly PT = \"pt\";\n\n public static readonly DIMENSIONLESS = new DimensionVector([\n 0, 0, 0, 0, 0, 0, 0, 1,\n ]);\n\n private static readonly INDEX_AMOUNT_OF_SUBSTANCE = 0;\n private static readonly INDEX_ELECTRIC_CURRENT = 1;\n private static readonly INDEX_LENGTH = 2;\n private static readonly INDEX_LUMINOUS_INTENSITY = 3;\n private static readonly INDEX_MASS = 4;\n private static readonly INDEX_TEMPERATURE = 5;\n private static readonly INDEX_TIME = 6;\n\n private readonly dimensionVectorIri: string;\n\n private readonly values: Array<number>;\n\n public static ofRequired(\n dimensionVectorIri: string | number[]\n ): DimensionVector {\n return new DimensionVector(dimensionVectorIri);\n }\n\n public static of(\n dimensionValues: string | number[]\n ): DimensionVector | undefined {\n try {\n return new DimensionVector(dimensionValues);\n } catch (e) {\n return undefined;\n }\n }\n\n constructor(dimensionVector: string | Array<number>) {\n if (typeof dimensionVector === \"string\") {\n this.dimensionVectorIri = dimensionVector;\n this.values = this.parseDimValues(dimensionVector);\n } else if (Array.isArray(dimensionVector)) {\n this.values = dimensionVector;\n this.dimensionVectorIri =\n this.generateDimensionVectorIri(dimensionVector);\n } else {\n throw new Error(`Cannot handle constructor argument ${dimensionVector}`);\n }\n }\n\n private parseDimValues(dimensionVectorIri: string): number[] {\n if (\n !QudtNamespaces.dimensionVector.isFullNamespaceIri(dimensionVectorIri)\n ) {\n throw new Error(`Not a dimension vector iri: ${dimensionVectorIri}`);\n }\n const localName =\n QudtNamespaces.dimensionVector.getLocalnameIfFullNamespaceIri(\n dimensionVectorIri\n );\n const dimValues = [0, 0, 0, 0, 0, 0, 0, 0];\n const numbers = localName.split(/[AELIMHTD]/);\n const indicators = localName.split(/-?[0-9]+p?t?[0-9]*/);\n if (indicators.length != 9) {\n throw new Error(\n `Cannot process dimension vector iri ${dimensionVectorIri}: unexpected number of dimensions: ${numbers.length}`\n );\n } else {\n for (let i = 0; i < 8; i++) {\n if (indicators[i].charAt(0) != DimensionVector.DIMENSIONS[i]) {\n throw new Error(\n `Expected dimension indicator '${DimensionVector.DIMENSIONS[i]}', encountered '${indicators[i]}'`\n );\n }\n dimValues[i] = DimensionVector.noNegativeZero(\n Number.parseFloat(numbers[i + 1].replace(\"pt\", \".\"))\n ); // split produces an empty first array element\n }\n }\n return dimValues;\n }\n\n private generateDimensionVectorIri(dimensionValues: number[]): string {\n if (dimensionValues.length != 8) {\n throw new Error(\n \"wrong dimensionality, expected 8, got \" + dimensionValues.length\n );\n }\n let result = \"\";\n for (let i = 0; i < 8; i++) {\n result +=\n DimensionVector.DIMENSIONS[i] +\n DimensionVector.iriFormat(dimensionValues[i]);\n }\n return \"http://qudt.org/vocab/dimensionvector/\" + result;\n }\n\n private static noNegativeZero(f: number): number {\n if (f === -0.0) {\n return 0.0;\n }\n return f;\n }\n\n private static iriFormat(dimensionValue: number): string {\n // Note: This handles a weird case where you may have \"-0\" as a value.\n if (Math.abs(dimensionValue) < 0.01) {\n return \"0\";\n }\n return DimensionVector.FORMAT.format(dimensionValue).replace(\".\", \"pt\");\n }\n\n public isDimensionless(): boolean {\n return this.equals(DimensionVector.DIMENSIONLESS);\n }\n\n public getDimensionVectorIri(): string {\n return this.dimensionVectorIri;\n }\n\n public getValues(): number[] {\n return this.values;\n }\n\n public getAmountOfSubstanceExponent() {\n return this.values[DimensionVector.INDEX_AMOUNT_OF_SUBSTANCE];\n }\n public getElectricCurrentExponent() {\n return this.values[DimensionVector.INDEX_ELECTRIC_CURRENT];\n }\n\n public getLenghExponent() {\n return this.values[DimensionVector.INDEX_LENGTH];\n }\n public getLuminousIntensityExponent() {\n return this.values[DimensionVector.INDEX_LUMINOUS_INTENSITY];\n }\n public getMassExponent() {\n return this.values[DimensionVector.INDEX_MASS];\n }\n public getTemperatureExponent() {\n return this.values[DimensionVector.INDEX_TEMPERATURE];\n }\n public getTimeExponent() {\n return this.values[DimensionVector.INDEX_TIME];\n }\n\n public multiply(by: number): DimensionVector {\n const mult: number[] = [];\n let isRatio = true;\n for (let i = 0; i < 7; i++) {\n const multDim = DimensionVector.noNegativeZero(this.values[i] * by);\n mult.push(multDim);\n if (multDim != 0) {\n isRatio = false;\n }\n }\n mult.push(0);\n DimensionVector.setRatio(mult, isRatio);\n return new DimensionVector(mult);\n }\n\n private static setRatio(values: number[], isRatio: boolean): void {\n values[7] = isRatio ? 1 : 0;\n }\n\n public combine(other: DimensionVector): DimensionVector {\n const combined: number[] = [];\n let isRatio = true;\n for (let i = 0; i < 7; i++) {\n combined[i] = DimensionVector.noNegativeZero(\n this.values[i] + other.getValues()[i]\n );\n if (combined[i] != 0) {\n isRatio = false;\n }\n }\n DimensionVector.setRatio(combined, isRatio);\n return new DimensionVector(combined);\n }\n\n public equals(o: unknown): boolean {\n if (isNullish(o)) {\n return false;\n }\n if (this === o) return true;\n if (!(o instanceof DimensionVector)) return false;\n const that = o as DimensionVector;\n return (\n that.getDimensionVectorIri() === this.dimensionVectorIri &&\n this.values.every((v, i) => v === that.getValues()[i])\n );\n }\n}\n"]}