Skip to content

Commit d038e2d

Browse files
committed
readme
1 parent 371ca60 commit d038e2d

File tree

2 files changed

+163
-1
lines changed

2 files changed

+163
-1
lines changed

README.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,164 @@
11
# tensorics-gson
2+
23
GSON bindings for tensorbacked objects
4+
5+
## Usage
6+
7+
In the simplest case, when coordinates of tensors are well dserializable by their string representation, then it is
8+
sufficient to register the adapter when creating the gson instance:
9+
10+
```java
11+
Gson gson=new GsonBuilder()
12+
.registerTypeAdapterFactory(TensorbackedGsonAdapter.FACTORY)
13+
.create();
14+
```
15+
16+
If we e.g. then assume, we have a tensorbacked object, defined as:
17+
18+
```java
19+
public interface AnInterfaceTensorbacked extends Tensorbacked2d<String, Integer, Double> {
20+
}
21+
```
22+
23+
with an example instance of:
24+
25+
```java
26+
AnInterfaceTensorbacked tb=Tensorics.builderFor(AnInterfaceTensorbacked.class)//
27+
.put(at("A",1),0.11)//
28+
.put(at("B",1),0.21)
29+
.put(at("A",2),0.12)//
30+
.put(at("B",2),0.22)
31+
.build();
32+
```
33+
34+
This can be serialized by:
35+
36+
```java
37+
String string=gson.toJson(tb);
38+
```
39+
40+
This results in a json string, containing a nested map, as:
41+
42+
```json
43+
{
44+
"A": {
45+
"1": 0.11,
46+
"2": 0.12
47+
},
48+
"B": {
49+
"1": 0.21,
50+
"2": 0.22
51+
}
52+
}
53+
```
54+
55+
Deserialization works like this:
56+
57+
```java
58+
AnInterfaceTensorbacked deserialized=simpleGson.fromJson(string,AnInterfaceTensorbacked.class);
59+
```
60+
61+
### Scalars
62+
63+
If the tensor is a scalar (it has no dimensions and contains exactly one entry), then it is serialized as a simple
64+
scalara value. E.g.:
65+
66+
```java
67+
public interface AScalarBacked extends TensorbackedScalar<Double> {
68+
}
69+
```
70+
71+
```java
72+
AScalarBacked val=Tensorics.builderForScalar(AScalarBacked.class)
73+
.put(0.33)
74+
.build();
75+
String string=simpleGson.toJson(val);
76+
```
77+
78+
results in the json string:
79+
80+
```json
81+
0.33
82+
```
83+
84+
### Complex coordinates
85+
86+
If maps are serialized into json, it gets problematic, if the keys are not simple types. In this case the keys would
87+
simply be serialized using the toString method, which results in invalid json strings, which cannot be deserialized
88+
anymore. To overcome this, gson offers an alternative way to serialize such maps, using 2-element arrays containing key
89+
and value for each map. As the tensorbacked adapter uses the standard gson map adapter, this is implemented out of the
90+
box for serialization and is also implemented for deserialization correctly.
91+
92+
E.g. let us assume, we have an object `Pair`
93+
94+
```java
95+
public class Pair {
96+
public final String a;
97+
public final String b;
98+
99+
public Pair(String a, String b) {
100+
this.a = a;
101+
this.b = b;
102+
}
103+
104+
/* valid hashcode, equals and toString methods (omitted here) */
105+
}
106+
```
107+
108+
... this we now want to use as a coordinate in a tensorbacked, e.g.:
109+
110+
```java
111+
public interface AComplexCoordTensorbacked extends Tensorbacked1d<Pair, Double> {
112+
}
113+
```
114+
115+
```java
116+
AComplexCoordTensorbacked complexCoordTb=Tensorics.builderFor(AComplexCoordTensorbacked.class)//
117+
.put(at(new Pair("a1","b1")),0.11)//
118+
.put(at(new Pair("a2","b2")),0.22)//
119+
.build();
120+
```
121+
122+
This would result in unvalid json, if we configure our gson instance like shown above. However, using the gson flag for
123+
complex map keys, can handle this situation:
124+
125+
```java
126+
Gson complexMapKeyGson=new GsonBuilder()//
127+
.registerTypeAdapterFactory(TensorbackedGsonAdapter.FACTORY)//
128+
.enableComplexMapKeySerialization() //
129+
.create();
130+
```
131+
132+
Using this for serialization, results in the following json:
133+
134+
```json
135+
[
136+
[
137+
{
138+
"a": "a1",
139+
"b": "b1"
140+
},
141+
0.11
142+
],
143+
[
144+
{
145+
"a": "a2",
146+
"b": "b2"
147+
},
148+
0.22
149+
]
150+
]
151+
```
152+
153+
Deserialization works with and without this flag, as the reader can detect the structure (i.e. the same behaviour as for
154+
maps)
155+
156+
## Remarks, current limitations and further thoughts
157+
158+
* A good starting point for further reading should be the test for the adapter, which shows some more specifics: [TensorbackedGsonAdapterTest](./src/test/java/org/tensorics/gson/adapters/TensorbackedGsonAdapterTest.java)
159+
* The context of the tensor is not serialized (and also not deserialized ;-) ... This ishard to change, as the types are
160+
not explizitely defined there.
161+
* With this complex map strategy, nested maps are strictly not necessary ... simply the Map<Position,Object> could be serialized ... To be seen what would be preferrrable wrt
162+
* json readibility
163+
* json size
164+
* Another idea could also be to even store the key once and e.g. introduce unique ids ... then having a keymap and a valuemap ... but probably even less readable and jsonic ;-)

src/test/java/org/tensorics/gson/adapters/TensorbackedGsonAdapterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public class TensorbackedGsonAdapterTest {
4646
.enableComplexMapKeySerialization() //
4747
.create();
4848

49-
5049
@Test
5150
public void simpleTensorSerializationIsOk() {
5251
String string = simpleGson.toJson(TENSORBACKED);
@@ -67,6 +66,7 @@ public void simpleScalarSerializationIsOk() {
6766
AScalarBacked val = Tensorics.builderForScalar(AScalarBacked.class).put(0.33).build();
6867

6968
String string = simpleGson.toJson(val);
69+
System.out.println(string);
7070
assertThat(string).isNotNull();
7171
assertThat(string).isNotEmpty();
7272
assertThat(string).isEqualTo("0.33");

0 commit comments

Comments
 (0)